[lonetix/bgp] Optimize BGP VM code by adding more terminating instructions and factorize their code; remove obsolete ASMTCH instruction, redirecting it to FASMTC
This commit is contained in:
parent
45d9b20b9e
commit
ae052ea987
123
lonetix/bgp/vm.c
123
lonetix/bgp/vm.c
|
@ -47,6 +47,8 @@
|
||||||
* by any VM and is always discarded by `Bgp_VmStoreMatch()`.
|
* by any VM and is always discarded by `Bgp_VmStoreMatch()`.
|
||||||
*/
|
*/
|
||||||
static Bgpvmmatch discardMatch;
|
static Bgpvmmatch discardMatch;
|
||||||
|
// Used for empty programs
|
||||||
|
static const Bgpvmbytec emptyProg = BGP_VMOP_END;
|
||||||
|
|
||||||
Judgement Bgp_InitVm(Bgpvm *vm, size_t heapSiz)
|
Judgement Bgp_InitVm(Bgpvm *vm, size_t heapSiz)
|
||||||
{
|
{
|
||||||
|
@ -64,6 +66,7 @@ Judgement Bgp_InitVm(Bgpvm *vm, size_t heapSiz)
|
||||||
vm->heap = heap;
|
vm->heap = heap;
|
||||||
vm->hMemSiz = siz;
|
vm->hMemSiz = siz;
|
||||||
vm->hHighMark = siz;
|
vm->hHighMark = siz;
|
||||||
|
vm->prog = (Bgpvmbytec *) &emptyProg;
|
||||||
return Bgp_SetErrStat(BGPENOERR);
|
return Bgp_SetErrStat(BGPENOERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,8 +79,12 @@ Judgement Bgp_VmEmit(Bgpvm *vm, Bgpvmbytec bytec)
|
||||||
|
|
||||||
if (vm->progLen + 1 >= vm->progCap) {
|
if (vm->progLen + 1 >= vm->progCap) {
|
||||||
// Grow the VM program segment
|
// Grow the VM program segment
|
||||||
|
Bgpvmbytec *oldProg = vm->prog;
|
||||||
|
if (vm->prog == &emptyProg)
|
||||||
|
oldProg = NULL;
|
||||||
|
|
||||||
size_t newSiz = vm->progCap + BGP_VM_GROWPROGN;
|
size_t newSiz = vm->progCap + BGP_VM_GROWPROGN;
|
||||||
Bgpvmbytec *newProg = (Bgpvmbytec *) realloc(vm->prog, newSiz * sizeof(*newProg));
|
Bgpvmbytec *newProg = (Bgpvmbytec *) realloc(oldProg, newSiz * sizeof(*newProg));
|
||||||
if (!newProg) {
|
if (!newProg) {
|
||||||
// Flag the VM as bad
|
// Flag the VM as bad
|
||||||
vm->setupFailed = TRUE;
|
vm->setupFailed = TRUE;
|
||||||
|
@ -157,7 +164,7 @@ Boolean Bgp_VmExec(Bgpvm *vm, Bgpmsg *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup initial VM state
|
// Setup initial VM state
|
||||||
Boolean result = TRUE; // assume PASS unless CFAIL says otherwise
|
Boolean result = TRUE; // assume pass unless found otherwise
|
||||||
|
|
||||||
vm->pc = 0;
|
vm->pc = 0;
|
||||||
vm->si = 0;
|
vm->si = 0;
|
||||||
|
@ -217,20 +224,29 @@ Boolean Bgp_VmExec(Bgpvm *vm, Bgpmsg *msg)
|
||||||
break;
|
break;
|
||||||
EXECUTE(NOT):
|
EXECUTE(NOT):
|
||||||
Bgp_VmDoNot(vm);
|
Bgp_VmDoNot(vm);
|
||||||
|
|
||||||
EXPECT(CFAIL, ir, vm);
|
|
||||||
EXPECT(CPASS, ir, vm);
|
|
||||||
break;
|
break;
|
||||||
EXECUTE(CFAIL):
|
EXECUTE(CFAIL):
|
||||||
if (Bgp_VmDoCfail(vm)) {
|
if (!Bgp_VmDoBreakPoint(vm, /*breakIf=*/TRUE, /*onBreak=*/FALSE)) {
|
||||||
result = FALSE; // immediate terminate on FAIL
|
result = FALSE; // immediate failure
|
||||||
goto terminate;
|
goto terminate;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
EXECUTE(CPASS):
|
EXECUTE(CPASS):
|
||||||
if (Bgp_VmDoCpass(vm))
|
if (!Bgp_VmDoBreakPoint(vm, /*breakIf=*/TRUE, /*onBreak=*/TRUE))
|
||||||
goto terminate; // immediate PASS
|
goto terminate; // immediate pass
|
||||||
|
|
||||||
|
break;
|
||||||
|
EXECUTE(ORFAIL):
|
||||||
|
if (!Bgp_VmDoBreakPoint(vm, /*breakIf=*/FALSE, /*onBreak=*/FALSE)) {
|
||||||
|
result = FALSE; // immediate failure
|
||||||
|
goto terminate;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
EXECUTE(ORPASS):
|
||||||
|
if (!Bgp_VmDoBreakPoint(vm, /*breakIf=*/FALSE, /*onBreak=*/TRUE))
|
||||||
|
goto terminate; // immediate pass
|
||||||
|
|
||||||
break;
|
break;
|
||||||
EXECUTE(JZ):
|
EXECUTE(JZ):
|
||||||
|
@ -243,9 +259,9 @@ Boolean Bgp_VmExec(Bgpvm *vm, Bgpmsg *msg)
|
||||||
if (vm->pc > vm->progLen) UNLIKELY
|
if (vm->pc > vm->progLen) UNLIKELY
|
||||||
vm->errCode = BGPEVMBADJMP; // jump target out of bounds
|
vm->errCode = BGPEVMBADJMP; // jump target out of bounds
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
BGP_VMPOP(vm); // no jump, pop the stack and move on
|
BGP_VMPOP(vm); // no jump, pop the stack and move on
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
EXECUTE(JNZ):
|
EXECUTE(JNZ):
|
||||||
if (!BGP_VMCHKSTKSIZ(vm, 1)) UNLIKELY
|
if (!BGP_VMCHKSTKSIZ(vm, 1)) UNLIKELY
|
||||||
|
@ -257,9 +273,9 @@ Boolean Bgp_VmExec(Bgpvm *vm, Bgpmsg *msg)
|
||||||
if (vm->pc > vm->progLen) UNLIKELY
|
if (vm->pc > vm->progLen) UNLIKELY
|
||||||
vm->errCode = BGPEVMBADJMP; // jump target out of bounds
|
vm->errCode = BGPEVMBADJMP; // jump target out of bounds
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
BGP_VMPOP(vm); // no jump, pop the stack and move on
|
BGP_VMPOP(vm); // no jump, pop the stack and move on
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
EXECUTE(CHKT):
|
EXECUTE(CHKT):
|
||||||
Bgp_VmDoChkt(vm, (BgpType) BGP_VMOPARG(ir));
|
Bgp_VmDoChkt(vm, (BgpType) BGP_VMOPARG(ir));
|
||||||
|
@ -282,9 +298,6 @@ Boolean Bgp_VmExec(Bgpvm *vm, Bgpmsg *msg)
|
||||||
EXECUTE(ASMTCH):
|
EXECUTE(ASMTCH):
|
||||||
Bgp_VmDoAsmtch(vm);
|
Bgp_VmDoAsmtch(vm);
|
||||||
break;
|
break;
|
||||||
EXECUTE(FASMTC):
|
|
||||||
Bgp_VmDoFasmtc(vm);
|
|
||||||
break;
|
|
||||||
EXECUTE(COMTCH):
|
EXECUTE(COMTCH):
|
||||||
Bgp_VmDoComtch(vm);
|
Bgp_VmDoComtch(vm);
|
||||||
break;
|
break;
|
||||||
|
@ -348,86 +361,43 @@ void Bgp_VmStoreMatch(Bgpvm *vm)
|
||||||
vm->nmatches++;
|
vm->nmatches++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Boolean Bgp_VmDoCpass(Bgpvm *vm)
|
Boolean Bgp_VmDoBreakPoint(Bgpvm *vm,
|
||||||
|
Boolean breakIf,
|
||||||
|
Boolean onBreak)
|
||||||
{
|
{
|
||||||
/* POPS:
|
/* POPS:
|
||||||
* -1: Last operation Boolean result (as a Sint64, 0 for FALSE)
|
* -1: Last operation Boolean result (as a Sint64, 0 for FALSE)
|
||||||
*
|
*
|
||||||
* PUSHES:
|
* PUSHES:
|
||||||
* * On PASS result:
|
* * On break result:
|
||||||
* - TRUE
|
* - `onBreak`
|
||||||
* * Otherwise:
|
* * Otherwise:
|
||||||
* - Nothing.
|
* - Nothing.
|
||||||
*
|
*
|
||||||
* SIDE-EFFECTS:
|
* SIDE-EFFECTS:
|
||||||
* - Breaks current BLK on PASS
|
* - Breaks current BLK if condition is met
|
||||||
* - Updates `curMatch->isPassing` flag accordingly
|
* - Updates `curMatch->isPassing` flag accordingly
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!BGP_VMCHKSTKSIZ(vm, 1)) UNLIKELY
|
if (!BGP_VMCHKSTKSIZ(vm, 1)) UNLIKELY
|
||||||
return FALSE; // error, let vm->errCode handle this
|
return TRUE; // error, let vm->errCode handle this
|
||||||
|
|
||||||
Boolean shouldTerm = FALSE; // unless proven otherwise
|
Boolean res = TRUE; // unless we're out of blocks
|
||||||
|
|
||||||
// If stack top is non-zero we FAIL
|
|
||||||
if (BGP_VMPEEK(vm, -1)) {
|
|
||||||
// Leave TRUE on stack and break current BLK, this is a PASS
|
|
||||||
vm->curMatch->isPassing = TRUE;
|
|
||||||
|
|
||||||
if (vm->nblk > 0)
|
|
||||||
Bgp_VmDoBreak(vm);
|
|
||||||
else
|
|
||||||
shouldTerm = TRUE; // no more BLK
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Pop the stack and move on, no PASS
|
|
||||||
vm->curMatch->isPassing = FALSE;
|
|
||||||
BGP_VMPOP(vm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Current match information has been collected,
|
|
||||||
// discard anything up to the next relevant operation
|
|
||||||
vm->curMatch = &discardMatch;
|
|
||||||
|
|
||||||
return shouldTerm;
|
|
||||||
}
|
|
||||||
|
|
||||||
Boolean Bgp_VmDoCfail(Bgpvm *vm)
|
|
||||||
{
|
|
||||||
/* POPS:
|
|
||||||
* -1: Last operation Boolean result (as a Sint64, 0 for FALSE)
|
|
||||||
*
|
|
||||||
* PUSHES:
|
|
||||||
* * On FAIL result:
|
|
||||||
* - FALSE
|
|
||||||
* * Otherwise:
|
|
||||||
* - Nothing.
|
|
||||||
*
|
|
||||||
* SIDE-EFFECTS:
|
|
||||||
* - Breaks current BLK on FAIL
|
|
||||||
* - Updates `curMatch->isPassing` flag accordingly
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!BGP_VMCHKSTKSIZ(vm, 1)) UNLIKELY
|
|
||||||
return FALSE; // error, let vm->errCode handle this
|
|
||||||
|
|
||||||
Boolean shouldTerm = FALSE; // unless proven otherwise
|
|
||||||
|
|
||||||
// If stack top is non-zero we FAIL
|
|
||||||
Bgpvmval *v = BGP_VMSTKGET(vm, -1);
|
Bgpvmval *v = BGP_VMSTKGET(vm, -1);
|
||||||
if (v->val) {
|
if (!!(v->val) == breakIf) {
|
||||||
// Push FALSE and break current BLK, this is a FAIL
|
// Push `onBreak` and break current BLK
|
||||||
vm->curMatch->isPassing = FALSE;
|
vm->curMatch->isPassing = onBreak;
|
||||||
|
|
||||||
v->val = FALSE;
|
v->val = onBreak;
|
||||||
if (vm->nblk > 0)
|
if (vm->nblk > 0)
|
||||||
Bgp_VmDoBreak(vm);
|
Bgp_VmDoBreak(vm);
|
||||||
else
|
else
|
||||||
shouldTerm = TRUE; // no more BLK
|
res = FALSE; // no more BLK
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Pop the stack and move on, no FAIL
|
// Pop the stack and move on, no break
|
||||||
vm->curMatch->isPassing = TRUE;
|
vm->curMatch->isPassing = !onBreak;
|
||||||
BGP_VMPOP(vm);
|
BGP_VMPOP(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +405,7 @@ Boolean Bgp_VmDoCfail(Bgpvm *vm)
|
||||||
// discard anything up to the next relevant operation
|
// discard anything up to the next relevant operation
|
||||||
vm->curMatch = &discardMatch;
|
vm->curMatch = &discardMatch;
|
||||||
|
|
||||||
return shouldTerm;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bgp_VmDoChkt(Bgpvm *vm, BgpType type)
|
void Bgp_VmDoChkt(Bgpvm *vm, BgpType type)
|
||||||
|
@ -813,5 +783,6 @@ void Bgp_ResetVm(Bgpvm *vm)
|
||||||
void Bgp_ClearVm(Bgpvm *vm)
|
void Bgp_ClearVm(Bgpvm *vm)
|
||||||
{
|
{
|
||||||
free(vm->heap);
|
free(vm->heap);
|
||||||
free(vm->prog);
|
if (vm->prog != &emptyProg)
|
||||||
|
free(vm->prog);
|
||||||
}
|
}
|
||||||
|
|
|
@ -741,65 +741,6 @@ void *Bgp_VmCompileAsMatch(Bgpvm *vm, const Asn *expression, size_t n)
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bgp_VmDoAsmtch(Bgpvm *vm)
|
void Bgp_VmDoAsmtch(Bgpvm *vm)
|
||||||
{
|
|
||||||
/* POPS:
|
|
||||||
* -1: Asn match array length
|
|
||||||
* -2: Address to Asn match array
|
|
||||||
*
|
|
||||||
* PUSHES:
|
|
||||||
* TRUE on successful match, FALSE otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
Nfacomp nc;
|
|
||||||
Nfa nfa;
|
|
||||||
Nfainst *buf, *prog;
|
|
||||||
|
|
||||||
if (!BGP_VMCHKSTK(vm, 2))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Pop arguments from stack
|
|
||||||
Sint64 n = BGP_VMPOP(vm);
|
|
||||||
const Asn *match = (const Asn *) BGP_VMPOPA(vm);
|
|
||||||
if (n <= 0 || match == NULL) {
|
|
||||||
vm->errCode = BGPEVMBADASMTCH;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!BGP_VMCHKMSGTYPE(vm, BGP_UPDATE)) {
|
|
||||||
Bgp_VmStoreMsgTypeMatch(vm, /*isMatching=*/FALSE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile on the fly on temporary memory
|
|
||||||
const size_t maxsiz = 6 * n * sizeof(*buf);
|
|
||||||
|
|
||||||
buf = (Nfainst *) Bgp_VmTempAlloc(vm, maxsiz);
|
|
||||||
if (!buf)
|
|
||||||
return;
|
|
||||||
|
|
||||||
compinit(&nc, buf);
|
|
||||||
|
|
||||||
int err; // compilation status
|
|
||||||
if ((err = setjmp(nc.oops)) != 0) {
|
|
||||||
vm->errCode = err;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
prog = compile(&nc, match, n);
|
|
||||||
#ifdef DF_DEBUG_ASMTCH
|
|
||||||
dumpprog(prog);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BgpvmRet status = execute(vm, prog, LISTSIZ, &nfa);
|
|
||||||
if (status == BGPEVMASMTCHESIZE)
|
|
||||||
status = execute(vm, prog, BIGLISTSIZ, &nfa);
|
|
||||||
|
|
||||||
Bgp_VmTempFree(vm, maxsiz);
|
|
||||||
|
|
||||||
if (status == BGPENOERR)
|
|
||||||
collect(vm, &nfa);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Bgp_VmDoFasmtc(Bgpvm *vm)
|
|
||||||
{
|
{
|
||||||
/* POPS:
|
/* POPS:
|
||||||
* -1: Precompiled NFA instructions
|
* -1: Precompiled NFA instructions
|
||||||
|
|
|
@ -41,6 +41,8 @@ static const char *OpcString(Bgpvmopc opc)
|
||||||
case BGP_VMOP_NOT: return "NOT";
|
case BGP_VMOP_NOT: return "NOT";
|
||||||
case BGP_VMOP_CFAIL: return "CFAIL";
|
case BGP_VMOP_CFAIL: return "CFAIL";
|
||||||
case BGP_VMOP_CPASS: return "CPASS";
|
case BGP_VMOP_CPASS: return "CPASS";
|
||||||
|
case BGP_VMOP_ORFAIL: return "ORFAIL";
|
||||||
|
case BGP_VMOP_ORPASS: return "ORPASS";
|
||||||
case BGP_VMOP_JZ: return "JZ";
|
case BGP_VMOP_JZ: return "JZ";
|
||||||
case BGP_VMOP_JNZ: return "JNZ";
|
case BGP_VMOP_JNZ: return "JNZ";
|
||||||
case BGP_VMOP_CHKT: return "CHKT";
|
case BGP_VMOP_CHKT: return "CHKT";
|
||||||
|
@ -50,7 +52,6 @@ static const char *OpcString(Bgpvmopc opc)
|
||||||
case BGP_VMOP_SUBN: return "SUBN";
|
case BGP_VMOP_SUBN: return "SUBN";
|
||||||
case BGP_VMOP_RELT: return "RELT";
|
case BGP_VMOP_RELT: return "RELT";
|
||||||
case BGP_VMOP_ASMTCH: return "ASMTCH";
|
case BGP_VMOP_ASMTCH: return "ASMTCH";
|
||||||
case BGP_VMOP_FASMTC: return "FASMTC";
|
|
||||||
case BGP_VMOP_COMTCH: return "COMTCH";
|
case BGP_VMOP_COMTCH: return "COMTCH";
|
||||||
case BGP_VMOP_ACOMTC: return "ACOMTC";
|
case BGP_VMOP_ACOMTC: return "ACOMTC";
|
||||||
case BGP_VMOP_END: return "END";
|
case BGP_VMOP_END: return "END";
|
||||||
|
@ -181,7 +182,7 @@ static char *CommentCodeLine(char *line, const char *comment)
|
||||||
|
|
||||||
void Bgp_VmDumpProgram(Bgpvm *vm, void *streamp, const StmOps *ops)
|
void Bgp_VmDumpProgram(Bgpvm *vm, void *streamp, const StmOps *ops)
|
||||||
{
|
{
|
||||||
char explainbuf[64];
|
char explainbuf[64];
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
int indent = 0;
|
int indent = 0;
|
||||||
|
@ -234,7 +235,7 @@ void Bgp_VmDumpProgram(Bgpvm *vm, void *streamp, const StmOps *ops)
|
||||||
|
|
||||||
p = Utoa(opa, p);
|
p = Utoa(opa, p);
|
||||||
if (opc == BGP_VMOP_JZ || opc == BGP_VMOP_JNZ)
|
if (opc == BGP_VMOP_JZ || opc == BGP_VMOP_JNZ)
|
||||||
opastr = ExplainJump(explainbuf, ip, opa, vm->progLen);
|
opastr = ExplainJump(explainbuf, ip, opa, vm->progLen);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case BGP_VMOP_TAG:
|
case BGP_VMOP_TAG:
|
||||||
|
|
|
@ -80,6 +80,8 @@ static void *const bgp_vmOpTab[256] = {
|
||||||
[BGP_VMOP_NOT] = &&EX_NOT,
|
[BGP_VMOP_NOT] = &&EX_NOT,
|
||||||
[BGP_VMOP_CFAIL] = &&EX_CFAIL,
|
[BGP_VMOP_CFAIL] = &&EX_CFAIL,
|
||||||
[BGP_VMOP_CPASS] = &&EX_CPASS,
|
[BGP_VMOP_CPASS] = &&EX_CPASS,
|
||||||
|
[BGP_VMOP_ORFAIL] = &&EX_ORFAIL,
|
||||||
|
[BGP_VMOP_ORPASS] = &&EX_ORPASS,
|
||||||
[BGP_VMOP_JZ] = &&EX_JZ,
|
[BGP_VMOP_JZ] = &&EX_JZ,
|
||||||
[BGP_VMOP_JNZ] = &&EX_JNZ,
|
[BGP_VMOP_JNZ] = &&EX_JNZ,
|
||||||
[BGP_VMOP_CHKT] = &&EX_CHKT,
|
[BGP_VMOP_CHKT] = &&EX_CHKT,
|
||||||
|
@ -89,7 +91,6 @@ static void *const bgp_vmOpTab[256] = {
|
||||||
[BGP_VMOP_SUBN] = &&EX_SUBN,
|
[BGP_VMOP_SUBN] = &&EX_SUBN,
|
||||||
[BGP_VMOP_RELT] = &&EX_RELT,
|
[BGP_VMOP_RELT] = &&EX_RELT,
|
||||||
[BGP_VMOP_ASMTCH] = &&EX_ASMTCH,
|
[BGP_VMOP_ASMTCH] = &&EX_ASMTCH,
|
||||||
[BGP_VMOP_FASMTC] = &&EX_FASMTC,
|
|
||||||
[BGP_VMOP_COMTCH] = &&EX_COMTCH,
|
[BGP_VMOP_COMTCH] = &&EX_COMTCH,
|
||||||
[BGP_VMOP_ACOMTC] = &&EX_ACOMTC,
|
[BGP_VMOP_ACOMTC] = &&EX_ACOMTC,
|
||||||
[BGP_VMOP_END] = &&EX_END
|
[BGP_VMOP_END] = &&EX_END
|
||||||
|
|
|
@ -75,26 +75,40 @@ FORCE_INLINE Uint8 BGP_VMOPARG(Bgpvmbytec bytec)
|
||||||
#define BGP_VMOP_TAG U8_C(8)
|
#define BGP_VMOP_TAG U8_C(8)
|
||||||
/// NOT - Boolean negate the topmost stack element
|
/// NOT - Boolean negate the topmost stack element
|
||||||
#define BGP_VMOP_NOT U8_C(9)
|
#define BGP_VMOP_NOT U8_C(9)
|
||||||
/// CONDITIONAL FAIL If TRUE - Fail the current matching `BLK` if topmost stack element is non-zero
|
/// CONDITIONAL FAIL If TRUE - Fail current match `BLK` if topmost stack element is non-zero
|
||||||
#define BGP_VMOP_CFAIL U8_C(10)
|
#define BGP_VMOP_CFAIL U8_C(10)
|
||||||
/// CONDITIONAL PASS If TRUE - Pass the current matching `BLK` if topmost stack element is non-zero
|
/// CONDITIONAL PASS If TRUE - Pass current match `BLK` if topmost stack element is non-zero
|
||||||
#define BGP_VMOP_CPASS U8_C(11)
|
#define BGP_VMOP_CPASS U8_C(11)
|
||||||
|
/// FAIL IF FALSE - Fail current match `BLK` if topmost stack element is zero
|
||||||
|
#define BGP_VMOP_ORFAIL U8_C(12)
|
||||||
|
/// PASS IF FALSE - Pass current match `BLK` if topmost stack element is zero
|
||||||
|
#define BGP_VMOP_ORPASS U8_C(13)
|
||||||
|
|
||||||
|
FORCE_INLINE Boolean BGP_ISVMOPBREAKING(Bgpvmopc opc)
|
||||||
|
{
|
||||||
|
return opc >= BGP_VMOP_CFAIL && opc <= BGP_VMOP_ORPASS;
|
||||||
|
}
|
||||||
|
|
||||||
/// Jump if zero - Skip over a positive number of instructions if topmost stack element is 0.
|
/// Jump if zero - Skip over a positive number of instructions if topmost stack element is 0.
|
||||||
#define BGP_VMOP_JZ U8_C(12)
|
#define BGP_VMOP_JZ U8_C(14)
|
||||||
/// Jump if non-zero - Skip over a positive number of instructions if topmost stack element is not 0.
|
/// Jump if non-zero - Skip over a positive number of instructions if topmost stack element is not 0.
|
||||||
#define BGP_VMOP_JNZ U8_C(13)
|
#define BGP_VMOP_JNZ U8_C(15)
|
||||||
|
|
||||||
|
FORCE_INLINE Boolean Bgp_ISVMOPJMP(Bgpvmopc opc)
|
||||||
|
{
|
||||||
|
return opc == BGP_VMOP_JZ || opc == BGP_VMOP_JNZ;
|
||||||
|
}
|
||||||
|
|
||||||
/// CHECK TYPE - ARG is the `BgpType` to test against
|
/// CHECK TYPE - ARG is the `BgpType` to test against
|
||||||
#define BGP_VMOP_CHKT U8_C(14)
|
#define BGP_VMOP_CHKT U8_C(16)
|
||||||
/// CHECK ATTRIBUTE - ARG is the `BgpAttrCode` to test for existence
|
/// CHECK ATTRIBUTE - ARG is the `BgpAttrCode` to test for existence
|
||||||
#define BGP_VMOP_CHKA U8_C(15)
|
#define BGP_VMOP_CHKA U8_C(17)
|
||||||
|
|
||||||
#define BGP_VMOP_EXCT U8_C(16)
|
#define BGP_VMOP_EXCT U8_C(18)
|
||||||
#define BGP_VMOP_SUPN U8_C(17)
|
#define BGP_VMOP_SUPN U8_C(19)
|
||||||
#define BGP_VMOP_SUBN U8_C(18)
|
#define BGP_VMOP_SUBN U8_C(20)
|
||||||
/// RELATED - Tests whether the BGP message contains prefixes related with the provided ones
|
/// RELATED - Tests whether the BGP message contains prefixes related with the provided ones
|
||||||
#define BGP_VMOP_RELT U8_C(19)
|
#define BGP_VMOP_RELT U8_C(21)
|
||||||
|
|
||||||
/// Returns `TRUE` if `opc` belongs to an instruction operating on NETwork prefixes.
|
/// Returns `TRUE` if `opc` belongs to an instruction operating on NETwork prefixes.
|
||||||
FORCE_INLINE Boolean BGP_ISVMOPNET(Bgpvmopc opc)
|
FORCE_INLINE Boolean BGP_ISVMOPNET(Bgpvmopc opc)
|
||||||
|
@ -102,17 +116,20 @@ FORCE_INLINE Boolean BGP_ISVMOPNET(Bgpvmopc opc)
|
||||||
return opc >= BGP_VMOP_EXCT && opc <= BGP_VMOP_RELT;
|
return opc >= BGP_VMOP_EXCT && opc <= BGP_VMOP_RELT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// AS PATH MATCH - Tests BGP message AS PATH against a match expression
|
/// AS PATH MATCH - Tests BGP message AS PATH against a precompiled match expression
|
||||||
#define BGP_VMOP_ASMTCH U8_C(20)
|
#define BGP_VMOP_ASMTCH U8_C(22)
|
||||||
/// FAST AS PATH MATCH - AS PATH test using precompiled AS PATH match expression
|
|
||||||
#define BGP_VMOP_FASMTC U8_C(21)
|
|
||||||
/// COMMUNITY MATCH - COMMUNITY test using a precompiled COMMUNITY match expression
|
/// COMMUNITY MATCH - COMMUNITY test using a precompiled COMMUNITY match expression
|
||||||
#define BGP_VMOP_COMTCH U8_C(22)
|
#define BGP_VMOP_COMTCH U8_C(23)
|
||||||
/// ALL COMMUNITY MATCH - Like COMTCH, but requires all communities to be present inside message
|
/// ALL COMMUNITY MATCH - Like COMTCH, but requires all communities to be present inside message
|
||||||
#define BGP_VMOP_ACOMTC U8_C(23)
|
#define BGP_VMOP_ACOMTC U8_C(24)
|
||||||
|
|
||||||
/// END - Terminate VM execution with the latest result
|
/// END - Terminate VM execution with the latest result
|
||||||
#define BGP_VMOP_END U8_C(24)
|
#define BGP_VMOP_END U8_C(25)
|
||||||
|
|
||||||
|
FORCE_INLINE Boolean BGP_ISVMOPENDING(Bgpvmopc opc)
|
||||||
|
{
|
||||||
|
return opc == BGP_VMOP_ENDBLK || opc == BGP_VMOP_END;
|
||||||
|
}
|
||||||
|
|
||||||
// #define BGP_VMOP_MOVK MOVE K - Move topmost K index to ARG K index
|
// #define BGP_VMOP_MOVK MOVE K - Move topmost K index to ARG K index
|
||||||
// #define BGP_VMOP_DISCRD DISCARD - discard vm->curMatch if any
|
// #define BGP_VMOP_DISCRD DISCARD - discard vm->curMatch if any
|
||||||
|
|
|
@ -201,10 +201,11 @@ FORCE_INLINE void Bgp_VmDoCall(Bgpvm *vm, Uint8 idx)
|
||||||
if (fn) fn(vm);
|
if (fn) fn(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implement `CPASS` (Conditional `PASS` if `TRUE`).
|
/**
|
||||||
Boolean Bgp_VmDoCpass(Bgpvm *vm);
|
* \brief Implement `CPASS`, `CFAIL`, `ORPASS`, `ORFAIL`, depending
|
||||||
/// Implement `CFAIL` (Conditional `FAIL` if `TRUE`).
|
* on break condition and value.
|
||||||
Boolean Bgp_VmDoCfail(Bgpvm *vm);
|
*/
|
||||||
|
Boolean Bgp_VmDoBreakPoint(Bgpvm *vm, Boolean breakIf, Boolean onBreak);
|
||||||
|
|
||||||
/// Implement `TAG` instruction with argument `tag`.
|
/// Implement `TAG` instruction with argument `tag`.
|
||||||
FORCE_INLINE void Bgp_VmDoTag(Bgpvm *vm, Uint8 tag)
|
FORCE_INLINE void Bgp_VmDoTag(Bgpvm *vm, Uint8 tag)
|
||||||
|
@ -242,7 +243,6 @@ void Bgp_VmDoSubn(Bgpvm *vm, Uint8 arg);
|
||||||
void Bgp_VmDoRelt(Bgpvm *vm, Uint8 arg);
|
void Bgp_VmDoRelt(Bgpvm *vm, Uint8 arg);
|
||||||
|
|
||||||
void Bgp_VmDoAsmtch(Bgpvm *vm);
|
void Bgp_VmDoAsmtch(Bgpvm *vm);
|
||||||
void Bgp_VmDoFasmtc(Bgpvm *vm);
|
|
||||||
|
|
||||||
void Bgp_VmDoComtch(Bgpvm *vm);
|
void Bgp_VmDoComtch(Bgpvm *vm);
|
||||||
void Bgp_VmDoAcomtc(Bgpvm *vm);
|
void Bgp_VmDoAcomtc(Bgpvm *vm);
|
||||||
|
|
Loading…
Reference in New Issue