diff --git a/src/nfa/limex_internal.h b/src/nfa/limex_internal.h index 1483a911..6bc9a597 100644 --- a/src/nfa/limex_internal.h +++ b/src/nfa/limex_internal.h @@ -99,24 +99,6 @@ enum LimExSquash { LIMEX_SQUASH_REPORT = 3 //!< squash when report is raised }; -struct LimExNFABase { - u8 reachMap[N_CHARS]; - u32 reachSize; - u32 accelCount; - u32 accelTableOffset; - u32 accelAuxCount; - u32 accelAuxOffset; - u32 acceptCount; - u32 acceptOffset; - u32 acceptEodCount; - u32 acceptEodOffset; - u32 exceptionCount; - u32 exceptionOffset; - u32 exReportOffset; - u32 repeatCount; - u32 repeatOffset; -}; - /* uniform looking types for the macros */ typedef u8 u_8; typedef u16 u_16; @@ -137,7 +119,7 @@ struct NFAException##size { \ u8 trigger; /**< from enum LimExTrigger */ \ }; \ \ -struct LimExNFA##size { /* MUST align with LimExNFABase */ \ +struct LimExNFA##size { \ u8 reachMap[N_CHARS]; /**< map of char -> entry in reach[] */ \ u32 reachSize; /**< number of reach masks */ \ u32 accelCount; /**< number of entries in accel table */ \ diff --git a/src/nfa/nfa_build_util.cpp b/src/nfa/nfa_build_util.cpp index 9244dcfb..ce473196 100644 --- a/src/nfa/nfa_build_util.cpp +++ b/src/nfa/nfa_build_util.cpp @@ -78,7 +78,7 @@ struct DISPATCH_BY_NFA_TYPE_INT { decltype(arg), (NFAEngineType)0>::doOp(i, arg) } -typedef bool (*has_accel_fn)(const NFA *nfa); +typedef bool (*nfa_dispatch_fn)(const NFA *nfa); template static @@ -87,8 +87,37 @@ bool has_accel_limex(const NFA *nfa) { return limex->accelCount; } +template static -bool has_accel_generic(const NFA *) { +bool has_repeats_limex(const NFA *nfa) { + const T *limex = (const T *)getImplNfa(nfa); + return limex->repeatCount; +} + + +template +static +bool has_repeats_other_than_firsts_limex(const NFA *nfa) { + const T *limex = (const T *)getImplNfa(nfa); + const char *ptr = (const char *)limex; + + const u32 *repeatOffset = (const u32 *)(ptr + limex->repeatOffset); + + for (u32 i = 0; i < limex->repeatCount; i++) { + u32 offset = repeatOffset[i]; + const NFARepeatInfo *info = (const NFARepeatInfo *)(ptr + offset); + const RepeatInfo *repeat = + (const RepeatInfo *)((const char *)info + sizeof(*info)); + if (repeat->type != REPEAT_FIRST) { + return true; + } + } + + return false; +} + +static +bool dispatch_false(const NFA *) { return false; } @@ -146,13 +175,20 @@ enum NFACategory {NFA_LIMEX, NFA_OTHER}; static const NFACategory category = NFA_LIMEX; \ typedef LimExNFA##mlt_size implNFA_t; \ typedef u_##mlt_size tableRow_t; \ - static const has_accel_fn has_accel; \ + static const nfa_dispatch_fn has_accel; \ + static const nfa_dispatch_fn has_repeats; \ + static const nfa_dispatch_fn has_repeats_other_than_firsts; \ static const u32 stateAlign = \ MAX(alignof(tableRow_t), alignof(RepeatControl)); \ static const bool fast = mlt_size <= 64; \ }; \ - const has_accel_fn NFATraits::has_accel \ + const nfa_dispatch_fn NFATraits::has_accel \ = has_accel_limex; \ + const nfa_dispatch_fn NFATraits::has_repeats \ + = has_repeats_limex; \ + const nfa_dispatch_fn \ + NFATraits::has_repeats_other_than_firsts \ + = has_repeats_other_than_firsts_limex; \ DO_IF_DUMP_SUPPORT( \ const char *NFATraits::name \ = "LimEx "#mlt_size; \ @@ -173,9 +209,13 @@ template<> struct NFATraits { static const NFACategory category = NFA_OTHER; static const u32 stateAlign = 1; static const bool fast = true; - static const has_accel_fn has_accel; + static const nfa_dispatch_fn has_accel; + static const nfa_dispatch_fn has_repeats; + static const nfa_dispatch_fn has_repeats_other_than_firsts; }; -const has_accel_fn NFATraits::has_accel = has_accel_dfa; +const nfa_dispatch_fn NFATraits::has_accel = has_accel_dfa; +const nfa_dispatch_fn NFATraits::has_repeats = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats_other_than_firsts = dispatch_false; #if defined(DUMP_SUPPORT) const char *NFATraits::name = "McClellan 8"; #endif @@ -185,9 +225,13 @@ template<> struct NFATraits { static const NFACategory category = NFA_OTHER; static const u32 stateAlign = 2; static const bool fast = true; - static const has_accel_fn has_accel; + static const nfa_dispatch_fn has_accel; + static const nfa_dispatch_fn has_repeats; + static const nfa_dispatch_fn has_repeats_other_than_firsts; }; -const has_accel_fn NFATraits::has_accel = has_accel_dfa; +const nfa_dispatch_fn NFATraits::has_accel = has_accel_dfa; +const nfa_dispatch_fn NFATraits::has_repeats = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats_other_than_firsts = dispatch_false; #if defined(DUMP_SUPPORT) const char *NFATraits::name = "McClellan 16"; #endif @@ -197,9 +241,13 @@ template<> struct NFATraits { static const NFACategory category = NFA_OTHER; static const u32 stateAlign = 8; static const bool fast = true; - static const has_accel_fn has_accel; + static const nfa_dispatch_fn has_accel; + static const nfa_dispatch_fn has_repeats; + static const nfa_dispatch_fn has_repeats_other_than_firsts; }; -const has_accel_fn NFATraits::has_accel = has_accel_dfa; +const nfa_dispatch_fn NFATraits::has_accel = has_accel_dfa; +const nfa_dispatch_fn NFATraits::has_repeats = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats_other_than_firsts = dispatch_false; #if defined(DUMP_SUPPORT) const char *NFATraits::name = "Goughfish 8"; #endif @@ -209,9 +257,13 @@ template<> struct NFATraits { static const NFACategory category = NFA_OTHER; static const u32 stateAlign = 8; static const bool fast = true; - static const has_accel_fn has_accel; + static const nfa_dispatch_fn has_accel; + static const nfa_dispatch_fn has_repeats; + static const nfa_dispatch_fn has_repeats_other_than_firsts; }; -const has_accel_fn NFATraits::has_accel = has_accel_dfa; +const nfa_dispatch_fn NFATraits::has_accel = has_accel_dfa; +const nfa_dispatch_fn NFATraits::has_repeats = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats_other_than_firsts = dispatch_false; #if defined(DUMP_SUPPORT) const char *NFATraits::name = "Goughfish 16"; #endif @@ -221,9 +273,13 @@ template<> struct NFATraits { static const NFACategory category = NFA_OTHER; static const u32 stateAlign = 8; static const bool fast = true; - static const has_accel_fn has_accel; + static const nfa_dispatch_fn has_accel; + static const nfa_dispatch_fn has_repeats; + static const nfa_dispatch_fn has_repeats_other_than_firsts; }; -const has_accel_fn NFATraits::has_accel = has_accel_generic; +const nfa_dispatch_fn NFATraits::has_accel = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats_other_than_firsts = dispatch_false; #if defined(DUMP_SUPPORT) const char *NFATraits::name = "Mega-Puff-Vac"; #endif @@ -233,9 +289,13 @@ template<> struct NFATraits { static const NFACategory category = NFA_OTHER; static const u32 stateAlign = 8; static const bool fast = true; - static const has_accel_fn has_accel; + static const nfa_dispatch_fn has_accel; + static const nfa_dispatch_fn has_repeats; + static const nfa_dispatch_fn has_repeats_other_than_firsts; }; -const has_accel_fn NFATraits::has_accel = has_accel_generic; +const nfa_dispatch_fn NFATraits::has_accel = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats_other_than_firsts = dispatch_false; #if defined(DUMP_SUPPORT) const char *NFATraits::name = "Castle"; #endif @@ -245,9 +305,13 @@ template<> struct NFATraits { static const NFACategory category = NFA_OTHER; static const u32 stateAlign = 8; static const bool fast = true; - static const has_accel_fn has_accel; + static const nfa_dispatch_fn has_accel; + static const nfa_dispatch_fn has_repeats; + static const nfa_dispatch_fn has_repeats_other_than_firsts; }; -const has_accel_fn NFATraits::has_accel = has_accel_generic; +const nfa_dispatch_fn NFATraits::has_accel = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats_other_than_firsts = dispatch_false; #if defined(DUMP_SUPPORT) const char *NFATraits::name = "Lim Bounded Repeat (D)"; #endif @@ -257,9 +321,13 @@ template<> struct NFATraits { static const NFACategory category = NFA_OTHER; static const u32 stateAlign = 8; static const bool fast = true; - static const has_accel_fn has_accel; + static const nfa_dispatch_fn has_accel; + static const nfa_dispatch_fn has_repeats; + static const nfa_dispatch_fn has_repeats_other_than_firsts; }; -const has_accel_fn NFATraits::has_accel = has_accel_generic; +const nfa_dispatch_fn NFATraits::has_accel = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats_other_than_firsts = dispatch_false; #if defined(DUMP_SUPPORT) const char *NFATraits::name = "Lim Bounded Repeat (V)"; #endif @@ -269,9 +337,13 @@ template<> struct NFATraits { static const NFACategory category = NFA_OTHER; static const u32 stateAlign = 8; static const bool fast = true; - static const has_accel_fn has_accel; + static const nfa_dispatch_fn has_accel; + static const nfa_dispatch_fn has_repeats; + static const nfa_dispatch_fn has_repeats_other_than_firsts; }; -const has_accel_fn NFATraits::has_accel = has_accel_generic; +const nfa_dispatch_fn NFATraits::has_accel = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats_other_than_firsts = dispatch_false; #if defined(DUMP_SUPPORT) const char *NFATraits::name = "Lim Bounded Repeat (NV)"; #endif @@ -281,9 +353,13 @@ template<> struct NFATraits { static const NFACategory category = NFA_OTHER; static const u32 stateAlign = 8; static const bool fast = true; - static const has_accel_fn has_accel; + static const nfa_dispatch_fn has_accel; + static const nfa_dispatch_fn has_repeats; + static const nfa_dispatch_fn has_repeats_other_than_firsts; }; -const has_accel_fn NFATraits::has_accel = has_accel_generic; +const nfa_dispatch_fn NFATraits::has_accel = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats_other_than_firsts = dispatch_false; #if defined(DUMP_SUPPORT) const char *NFATraits::name = "Lim Bounded Repeat (S)"; #endif @@ -293,9 +369,13 @@ template<> struct NFATraits { static const NFACategory category = NFA_OTHER; static const u32 stateAlign = 8; static const bool fast = true; - static const has_accel_fn has_accel; + static const nfa_dispatch_fn has_accel; + static const nfa_dispatch_fn has_repeats; + static const nfa_dispatch_fn has_repeats_other_than_firsts; }; -const has_accel_fn NFATraits::has_accel = has_accel_generic; +const nfa_dispatch_fn NFATraits::has_accel = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats_other_than_firsts = dispatch_false; #if defined(DUMP_SUPPORT) const char *NFATraits::name = "Lim Bounded Repeat (M)"; #endif @@ -305,9 +385,13 @@ template<> struct NFATraits { static const NFACategory category = NFA_OTHER; static const u32 stateAlign = 32; static const bool fast = true; - static const has_accel_fn has_accel; + static const nfa_dispatch_fn has_accel; + static const nfa_dispatch_fn has_repeats; + static const nfa_dispatch_fn has_repeats_other_than_firsts; }; -const has_accel_fn NFATraits::has_accel = has_accel_generic; +const nfa_dispatch_fn NFATraits::has_accel = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats = dispatch_false; +const nfa_dispatch_fn NFATraits::has_repeats_other_than_firsts = dispatch_false; #if defined(DUMP_SUPPORT) const char *NFATraits::name = "Tamarama"; #endif @@ -362,42 +446,39 @@ struct is_limex { }; } +namespace { +template +struct has_repeats_other_than_firsts_dispatch { + static nfa_dispatch_fn call(const void *) { + return NFATraits::has_repeats_other_than_firsts; + } +}; +} + bool has_bounded_repeats_other_than_firsts(const NFA &nfa) { - if (!DISPATCH_BY_NFA_TYPE((NFAEngineType)nfa.type, is_limex, &nfa)) { - return false; + return DISPATCH_BY_NFA_TYPE((NFAEngineType)nfa.type, + has_repeats_other_than_firsts_dispatch, + &nfa)(&nfa); +} + +namespace { +template +struct has_repeats_dispatch { + static nfa_dispatch_fn call(const void *) { + return NFATraits::has_repeats; } - - const LimExNFABase *limex = (const LimExNFABase *)getImplNfa(&nfa); - const char *ptr = (const char *)limex; - - const u32 *repeatOffset = (const u32 *)(ptr + limex->repeatOffset); - - for (u32 i = 0; i < limex->repeatCount; i++) { - u32 offset = repeatOffset[i]; - const NFARepeatInfo *info = (const NFARepeatInfo *)(ptr + offset); - const RepeatInfo *repeat = - (const RepeatInfo *)((const char *)info + sizeof(*info)); - if (repeat->type != REPEAT_FIRST) { - return true; - } - } - - return false; +}; } bool has_bounded_repeats(const NFA &nfa) { - if (!DISPATCH_BY_NFA_TYPE((NFAEngineType)nfa.type, is_limex, &nfa)) { - return false; - } - - const LimExNFABase *limex = (const LimExNFABase *)getImplNfa(&nfa); - return limex->repeatCount; + return DISPATCH_BY_NFA_TYPE((NFAEngineType)nfa.type, has_repeats_dispatch, + &nfa)(&nfa); } namespace { template struct has_accel_dispatch { - static has_accel_fn call(const void *) { + static nfa_dispatch_fn call(const void *) { return NFATraits::has_accel; } }; @@ -405,8 +486,7 @@ struct has_accel_dispatch { bool has_accel(const NFA &nfa) { return DISPATCH_BY_NFA_TYPE((NFAEngineType)nfa.type, has_accel_dispatch, - &nfa) - (&nfa); + &nfa)(&nfa); } bool requires_decompress_key(const NFA &nfa) {