1 | /* |
2 | * Copyright (c) 2015-2017, Intel Corporation |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions are met: |
6 | * |
7 | * * Redistributions of source code must retain the above copyright notice, |
8 | * this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of Intel Corporation nor the names of its contributors |
13 | * may be used to endorse or promote products derived from this software |
14 | * without specific prior written permission. |
15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | * POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
28 | |
29 | #include "nfa_build_util.h" |
30 | |
31 | #include "limex_internal.h" |
32 | #include "mcclellancompile.h" |
33 | #include "mcsheng_compile.h" |
34 | #include "shengcompile.h" |
35 | #include "nfa_internal.h" |
36 | #include "repeat_internal.h" |
37 | #include "ue2common.h" |
38 | |
39 | #include <algorithm> |
40 | #include <cassert> |
41 | #include <cstddef> |
42 | #include <cstdio> |
43 | #include <cstdlib> |
44 | #include <cstring> |
45 | #include <sstream> |
46 | |
47 | using namespace std; |
48 | |
49 | namespace ue2 { |
50 | |
51 | namespace { |
52 | |
53 | template<NFAEngineType t> struct NFATraits { }; |
54 | |
55 | template<template<NFAEngineType t> class sfunc, typename rv_t, typename arg_t, |
56 | NFAEngineType lb> |
57 | struct DISPATCH_BY_NFA_TYPE_INT { |
58 | static rv_t doOp(NFAEngineType i, const arg_t &arg) { |
59 | if (i == lb) { |
60 | return sfunc<lb>::call(arg); |
61 | } else { |
62 | return DISPATCH_BY_NFA_TYPE_INT<sfunc, rv_t, arg_t, |
63 | (NFAEngineType)(lb + 1)> |
64 | ::doOp(i, arg); |
65 | } |
66 | } |
67 | }; |
68 | |
69 | template<template<NFAEngineType t> class sfunc, typename rv_t, typename arg_t> |
70 | struct DISPATCH_BY_NFA_TYPE_INT<sfunc, rv_t, arg_t, INVALID_NFA> { |
71 | // dummy |
72 | static rv_t doOp(NFAEngineType, const arg_t &) { |
73 | assert(0); |
74 | throw std::logic_error("Unreachable" ); |
75 | } |
76 | }; |
77 | |
78 | #define DISPATCH_BY_NFA_TYPE(i, op, arg) \ |
79 | DISPATCH_BY_NFA_TYPE_INT<op, decltype(op<(NFAEngineType)0>::call(arg)), \ |
80 | decltype(arg), (NFAEngineType)0>::doOp(i, arg) |
81 | } |
82 | |
83 | typedef bool (*nfa_dispatch_fn)(const NFA *nfa); |
84 | |
85 | template<typename T> |
86 | static |
87 | bool has_accel_limex(const NFA *nfa) { |
88 | const T *limex = (const T *)getImplNfa(nfa); |
89 | return limex->accelCount; |
90 | } |
91 | |
92 | template<typename T> |
93 | static |
94 | bool has_repeats_limex(const NFA *nfa) { |
95 | const T *limex = (const T *)getImplNfa(nfa); |
96 | return limex->repeatCount; |
97 | } |
98 | |
99 | |
100 | template<typename T> |
101 | static |
102 | bool has_repeats_other_than_firsts_limex(const NFA *nfa) { |
103 | const T *limex = (const T *)getImplNfa(nfa); |
104 | const char *ptr = (const char *)limex; |
105 | |
106 | const u32 *repeatOffset = (const u32 *)(ptr + limex->repeatOffset); |
107 | |
108 | for (u32 i = 0; i < limex->repeatCount; i++) { |
109 | u32 offset = repeatOffset[i]; |
110 | const NFARepeatInfo *info = (const NFARepeatInfo *)(ptr + offset); |
111 | const RepeatInfo *repeat = |
112 | (const RepeatInfo *)((const char *)info + sizeof(*info)); |
113 | if (repeat->type != REPEAT_FIRST) { |
114 | return true; |
115 | } |
116 | } |
117 | |
118 | return false; |
119 | } |
120 | |
121 | static |
122 | bool dispatch_false(const NFA *) { |
123 | return false; |
124 | } |
125 | |
126 | #ifdef DUMP_SUPPORT |
127 | namespace { |
128 | template<NFAEngineType t> |
129 | struct getName { |
130 | static const char *call(void *) { |
131 | return NFATraits<t>::name; |
132 | } |
133 | }; |
134 | |
135 | // descr helper for LimEx NFAs |
136 | template<NFAEngineType t> |
137 | static |
138 | string getDescriptionLimEx(const NFA *nfa) { |
139 | const typename NFATraits<t>::implNFA_t *limex = |
140 | (const typename NFATraits<t>::implNFA_t *)getImplNfa(nfa); |
141 | ostringstream oss; |
142 | oss << NFATraits<t>::name << "/" << limex->exceptionCount; |
143 | if (limex->repeatCount) { |
144 | oss << " +" << limex->repeatCount << "r" ; |
145 | } |
146 | return oss.str(); |
147 | } |
148 | } |
149 | |
150 | // generic description: just return the name |
151 | namespace { |
152 | template<NFAEngineType t> |
153 | struct getDescription { |
154 | static string call(const void *) { |
155 | return string(NFATraits<t>::name); |
156 | } |
157 | }; |
158 | } |
159 | #endif |
160 | |
161 | |
162 | /* build-utility Traits */ |
163 | |
164 | namespace { |
165 | enum NFACategory {NFA_LIMEX, NFA_OTHER}; |
166 | |
167 | // Some of our traits we want around in DUMP_SUPPORT mode only. |
168 | #if defined(DUMP_SUPPORT) |
169 | #define DO_IF_DUMP_SUPPORT(a) a |
170 | #else |
171 | #define DO_IF_DUMP_SUPPORT(a) |
172 | #endif |
173 | |
174 | #define MAKE_LIMEX_TRAITS(mlt_size, mlt_align) \ |
175 | template<> struct NFATraits<LIMEX_NFA_##mlt_size> { \ |
176 | static UNUSED const char *name; \ |
177 | static const NFACategory category = NFA_LIMEX; \ |
178 | typedef LimExNFA##mlt_size implNFA_t; \ |
179 | static const nfa_dispatch_fn has_accel; \ |
180 | static const nfa_dispatch_fn has_repeats; \ |
181 | static const nfa_dispatch_fn has_repeats_other_than_firsts; \ |
182 | static const u32 stateAlign = \ |
183 | MAX(mlt_align, alignof(RepeatControl)); \ |
184 | static const bool fast = mlt_size <= 64; \ |
185 | }; \ |
186 | const nfa_dispatch_fn NFATraits<LIMEX_NFA_##mlt_size>::has_accel \ |
187 | = has_accel_limex<LimExNFA##mlt_size>; \ |
188 | const nfa_dispatch_fn NFATraits<LIMEX_NFA_##mlt_size>::has_repeats \ |
189 | = has_repeats_limex<LimExNFA##mlt_size>; \ |
190 | const nfa_dispatch_fn \ |
191 | NFATraits<LIMEX_NFA_##mlt_size>::has_repeats_other_than_firsts \ |
192 | = has_repeats_other_than_firsts_limex<LimExNFA##mlt_size>; \ |
193 | DO_IF_DUMP_SUPPORT( \ |
194 | const char *NFATraits<LIMEX_NFA_##mlt_size>::name \ |
195 | = "LimEx "#mlt_size; \ |
196 | template<> struct getDescription<LIMEX_NFA_##mlt_size> { \ |
197 | static string call(const void *p) { \ |
198 | return getDescriptionLimEx<LIMEX_NFA_##mlt_size>((const NFA *)p); \ |
199 | } \ |
200 | };) |
201 | |
202 | MAKE_LIMEX_TRAITS(32, alignof(u32)) |
203 | MAKE_LIMEX_TRAITS(64, alignof(m128)) /* special, 32bit arch uses m128 */ |
204 | MAKE_LIMEX_TRAITS(128, alignof(m128)) |
205 | MAKE_LIMEX_TRAITS(256, alignof(m256)) |
206 | MAKE_LIMEX_TRAITS(384, alignof(m384)) |
207 | MAKE_LIMEX_TRAITS(512, alignof(m512)) |
208 | |
209 | template<> struct NFATraits<MCCLELLAN_NFA_8> { |
210 | UNUSED static const char *name; |
211 | static const NFACategory category = NFA_OTHER; |
212 | static const u32 stateAlign = 1; |
213 | static const bool fast = true; |
214 | static const nfa_dispatch_fn has_accel; |
215 | static const nfa_dispatch_fn has_repeats; |
216 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
217 | }; |
218 | const nfa_dispatch_fn NFATraits<MCCLELLAN_NFA_8>::has_accel = has_accel_mcclellan; |
219 | const nfa_dispatch_fn NFATraits<MCCLELLAN_NFA_8>::has_repeats = dispatch_false; |
220 | const nfa_dispatch_fn NFATraits<MCCLELLAN_NFA_8>::has_repeats_other_than_firsts = dispatch_false; |
221 | #if defined(DUMP_SUPPORT) |
222 | const char *NFATraits<MCCLELLAN_NFA_8>::name = "McClellan 8" ; |
223 | #endif |
224 | |
225 | template<> struct NFATraits<MCCLELLAN_NFA_16> { |
226 | UNUSED static const char *name; |
227 | static const NFACategory category = NFA_OTHER; |
228 | static const u32 stateAlign = 2; |
229 | static const bool fast = true; |
230 | static const nfa_dispatch_fn has_accel; |
231 | static const nfa_dispatch_fn has_repeats; |
232 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
233 | }; |
234 | const nfa_dispatch_fn NFATraits<MCCLELLAN_NFA_16>::has_accel = has_accel_mcclellan; |
235 | const nfa_dispatch_fn NFATraits<MCCLELLAN_NFA_16>::has_repeats = dispatch_false; |
236 | const nfa_dispatch_fn NFATraits<MCCLELLAN_NFA_16>::has_repeats_other_than_firsts = dispatch_false; |
237 | #if defined(DUMP_SUPPORT) |
238 | const char *NFATraits<MCCLELLAN_NFA_16>::name = "McClellan 16" ; |
239 | #endif |
240 | |
241 | template<> struct NFATraits<GOUGH_NFA_8> { |
242 | UNUSED static const char *name; |
243 | static const NFACategory category = NFA_OTHER; |
244 | static const u32 stateAlign = 8; |
245 | static const bool fast = true; |
246 | static const nfa_dispatch_fn has_accel; |
247 | static const nfa_dispatch_fn has_repeats; |
248 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
249 | }; |
250 | const nfa_dispatch_fn NFATraits<GOUGH_NFA_8>::has_accel = has_accel_mcclellan; |
251 | const nfa_dispatch_fn NFATraits<GOUGH_NFA_8>::has_repeats = dispatch_false; |
252 | const nfa_dispatch_fn NFATraits<GOUGH_NFA_8>::has_repeats_other_than_firsts = dispatch_false; |
253 | #if defined(DUMP_SUPPORT) |
254 | const char *NFATraits<GOUGH_NFA_8>::name = "Goughfish 8" ; |
255 | #endif |
256 | |
257 | template<> struct NFATraits<GOUGH_NFA_16> { |
258 | UNUSED static const char *name; |
259 | static const NFACategory category = NFA_OTHER; |
260 | static const u32 stateAlign = 8; |
261 | static const bool fast = true; |
262 | static const nfa_dispatch_fn has_accel; |
263 | static const nfa_dispatch_fn has_repeats; |
264 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
265 | }; |
266 | const nfa_dispatch_fn NFATraits<GOUGH_NFA_16>::has_accel = has_accel_mcclellan; |
267 | const nfa_dispatch_fn NFATraits<GOUGH_NFA_16>::has_repeats = dispatch_false; |
268 | const nfa_dispatch_fn NFATraits<GOUGH_NFA_16>::has_repeats_other_than_firsts = dispatch_false; |
269 | #if defined(DUMP_SUPPORT) |
270 | const char *NFATraits<GOUGH_NFA_16>::name = "Goughfish 16" ; |
271 | #endif |
272 | |
273 | template<> struct NFATraits<MPV_NFA> { |
274 | UNUSED static const char *name; |
275 | static const NFACategory category = NFA_OTHER; |
276 | static const u32 stateAlign = 8; |
277 | static const bool fast = true; |
278 | static const nfa_dispatch_fn has_accel; |
279 | static const nfa_dispatch_fn has_repeats; |
280 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
281 | }; |
282 | const nfa_dispatch_fn NFATraits<MPV_NFA>::has_accel = dispatch_false; |
283 | const nfa_dispatch_fn NFATraits<MPV_NFA>::has_repeats = dispatch_false; |
284 | const nfa_dispatch_fn NFATraits<MPV_NFA>::has_repeats_other_than_firsts = dispatch_false; |
285 | #if defined(DUMP_SUPPORT) |
286 | const char *NFATraits<MPV_NFA>::name = "Mega-Puff-Vac" ; |
287 | #endif |
288 | |
289 | template<> struct NFATraits<CASTLE_NFA> { |
290 | UNUSED static const char *name; |
291 | static const NFACategory category = NFA_OTHER; |
292 | static const u32 stateAlign = 8; |
293 | static const bool fast = true; |
294 | static const nfa_dispatch_fn has_accel; |
295 | static const nfa_dispatch_fn has_repeats; |
296 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
297 | }; |
298 | const nfa_dispatch_fn NFATraits<CASTLE_NFA>::has_accel = dispatch_false; |
299 | const nfa_dispatch_fn NFATraits<CASTLE_NFA>::has_repeats = dispatch_false; |
300 | const nfa_dispatch_fn NFATraits<CASTLE_NFA>::has_repeats_other_than_firsts = dispatch_false; |
301 | #if defined(DUMP_SUPPORT) |
302 | const char *NFATraits<CASTLE_NFA>::name = "Castle" ; |
303 | #endif |
304 | |
305 | template<> struct NFATraits<LBR_NFA_DOT> { |
306 | UNUSED static const char *name; |
307 | static const NFACategory category = NFA_OTHER; |
308 | static const u32 stateAlign = 8; |
309 | static const bool fast = true; |
310 | static const nfa_dispatch_fn has_accel; |
311 | static const nfa_dispatch_fn has_repeats; |
312 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
313 | }; |
314 | const nfa_dispatch_fn NFATraits<LBR_NFA_DOT>::has_accel = dispatch_false; |
315 | const nfa_dispatch_fn NFATraits<LBR_NFA_DOT>::has_repeats = dispatch_false; |
316 | const nfa_dispatch_fn NFATraits<LBR_NFA_DOT>::has_repeats_other_than_firsts = dispatch_false; |
317 | #if defined(DUMP_SUPPORT) |
318 | const char *NFATraits<LBR_NFA_DOT>::name = "Lim Bounded Repeat (D)" ; |
319 | #endif |
320 | |
321 | template<> struct NFATraits<LBR_NFA_VERM> { |
322 | UNUSED static const char *name; |
323 | static const NFACategory category = NFA_OTHER; |
324 | static const u32 stateAlign = 8; |
325 | static const bool fast = true; |
326 | static const nfa_dispatch_fn has_accel; |
327 | static const nfa_dispatch_fn has_repeats; |
328 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
329 | }; |
330 | const nfa_dispatch_fn NFATraits<LBR_NFA_VERM>::has_accel = dispatch_false; |
331 | const nfa_dispatch_fn NFATraits<LBR_NFA_VERM>::has_repeats = dispatch_false; |
332 | const nfa_dispatch_fn NFATraits<LBR_NFA_VERM>::has_repeats_other_than_firsts = dispatch_false; |
333 | #if defined(DUMP_SUPPORT) |
334 | const char *NFATraits<LBR_NFA_VERM>::name = "Lim Bounded Repeat (V)" ; |
335 | #endif |
336 | |
337 | template<> struct NFATraits<LBR_NFA_NVERM> { |
338 | UNUSED static const char *name; |
339 | static const NFACategory category = NFA_OTHER; |
340 | static const u32 stateAlign = 8; |
341 | static const bool fast = true; |
342 | static const nfa_dispatch_fn has_accel; |
343 | static const nfa_dispatch_fn has_repeats; |
344 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
345 | }; |
346 | const nfa_dispatch_fn NFATraits<LBR_NFA_NVERM>::has_accel = dispatch_false; |
347 | const nfa_dispatch_fn NFATraits<LBR_NFA_NVERM>::has_repeats = dispatch_false; |
348 | const nfa_dispatch_fn NFATraits<LBR_NFA_NVERM>::has_repeats_other_than_firsts = dispatch_false; |
349 | #if defined(DUMP_SUPPORT) |
350 | const char *NFATraits<LBR_NFA_NVERM>::name = "Lim Bounded Repeat (NV)" ; |
351 | #endif |
352 | |
353 | template<> struct NFATraits<LBR_NFA_SHUF> { |
354 | UNUSED static const char *name; |
355 | static const NFACategory category = NFA_OTHER; |
356 | static const u32 stateAlign = 8; |
357 | static const bool fast = true; |
358 | static const nfa_dispatch_fn has_accel; |
359 | static const nfa_dispatch_fn has_repeats; |
360 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
361 | }; |
362 | const nfa_dispatch_fn NFATraits<LBR_NFA_SHUF>::has_accel = dispatch_false; |
363 | const nfa_dispatch_fn NFATraits<LBR_NFA_SHUF>::has_repeats = dispatch_false; |
364 | const nfa_dispatch_fn NFATraits<LBR_NFA_SHUF>::has_repeats_other_than_firsts = dispatch_false; |
365 | #if defined(DUMP_SUPPORT) |
366 | const char *NFATraits<LBR_NFA_SHUF>::name = "Lim Bounded Repeat (S)" ; |
367 | #endif |
368 | |
369 | template<> struct NFATraits<LBR_NFA_TRUF> { |
370 | UNUSED static const char *name; |
371 | static const NFACategory category = NFA_OTHER; |
372 | static const u32 stateAlign = 8; |
373 | static const bool fast = true; |
374 | static const nfa_dispatch_fn has_accel; |
375 | static const nfa_dispatch_fn has_repeats; |
376 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
377 | }; |
378 | const nfa_dispatch_fn NFATraits<LBR_NFA_TRUF>::has_accel = dispatch_false; |
379 | const nfa_dispatch_fn NFATraits<LBR_NFA_TRUF>::has_repeats = dispatch_false; |
380 | const nfa_dispatch_fn NFATraits<LBR_NFA_TRUF>::has_repeats_other_than_firsts = dispatch_false; |
381 | #if defined(DUMP_SUPPORT) |
382 | const char *NFATraits<LBR_NFA_TRUF>::name = "Lim Bounded Repeat (M)" ; |
383 | #endif |
384 | |
385 | template<> struct NFATraits<SHENG_NFA> { |
386 | UNUSED static const char *name; |
387 | static const NFACategory category = NFA_OTHER; |
388 | static const u32 stateAlign = 1; |
389 | static const bool fast = true; |
390 | static const nfa_dispatch_fn has_accel; |
391 | static const nfa_dispatch_fn has_repeats; |
392 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
393 | }; |
394 | const nfa_dispatch_fn NFATraits<SHENG_NFA>::has_accel = has_accel_sheng; |
395 | const nfa_dispatch_fn NFATraits<SHENG_NFA>::has_repeats = dispatch_false; |
396 | const nfa_dispatch_fn NFATraits<SHENG_NFA>::has_repeats_other_than_firsts = dispatch_false; |
397 | #if defined(DUMP_SUPPORT) |
398 | const char *NFATraits<SHENG_NFA>::name = "Sheng" ; |
399 | #endif |
400 | |
401 | template<> struct NFATraits<TAMARAMA_NFA> { |
402 | UNUSED static const char *name; |
403 | static const NFACategory category = NFA_OTHER; |
404 | static const u32 stateAlign = 64; |
405 | static const bool fast = true; |
406 | static const nfa_dispatch_fn has_accel; |
407 | static const nfa_dispatch_fn has_repeats; |
408 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
409 | }; |
410 | const nfa_dispatch_fn NFATraits<TAMARAMA_NFA>::has_accel = dispatch_false; |
411 | const nfa_dispatch_fn NFATraits<TAMARAMA_NFA>::has_repeats = dispatch_false; |
412 | const nfa_dispatch_fn NFATraits<TAMARAMA_NFA>::has_repeats_other_than_firsts = dispatch_false; |
413 | #if defined(DUMP_SUPPORT) |
414 | const char *NFATraits<TAMARAMA_NFA>::name = "Tamarama" ; |
415 | #endif |
416 | |
417 | template<> struct NFATraits<MCSHENG_NFA_8> { |
418 | UNUSED static const char *name; |
419 | static const NFACategory category = NFA_OTHER; |
420 | static const u32 stateAlign = 1; |
421 | static const bool fast = true; |
422 | static const nfa_dispatch_fn has_accel; |
423 | static const nfa_dispatch_fn has_repeats; |
424 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
425 | }; |
426 | const nfa_dispatch_fn NFATraits<MCSHENG_NFA_8>::has_accel = has_accel_mcsheng; |
427 | const nfa_dispatch_fn NFATraits<MCSHENG_NFA_8>::has_repeats = dispatch_false; |
428 | const nfa_dispatch_fn NFATraits<MCSHENG_NFA_8>::has_repeats_other_than_firsts = dispatch_false; |
429 | #if defined(DUMP_SUPPORT) |
430 | const char *NFATraits<MCSHENG_NFA_8>::name = "Shengy McShengFace 8" ; |
431 | #endif |
432 | |
433 | template<> struct NFATraits<MCSHENG_NFA_16> { |
434 | UNUSED static const char *name; |
435 | static const NFACategory category = NFA_OTHER; |
436 | static const u32 stateAlign = 2; |
437 | static const bool fast = true; |
438 | static const nfa_dispatch_fn has_accel; |
439 | static const nfa_dispatch_fn has_repeats; |
440 | static const nfa_dispatch_fn has_repeats_other_than_firsts; |
441 | }; |
442 | const nfa_dispatch_fn NFATraits<MCSHENG_NFA_16>::has_accel = has_accel_mcsheng; |
443 | const nfa_dispatch_fn NFATraits<MCSHENG_NFA_16>::has_repeats = dispatch_false; |
444 | const nfa_dispatch_fn NFATraits<MCSHENG_NFA_16>::has_repeats_other_than_firsts = dispatch_false; |
445 | #if defined(DUMP_SUPPORT) |
446 | const char *NFATraits<MCSHENG_NFA_16>::name = "Shengy McShengFace 16" ; |
447 | #endif |
448 | |
449 | } // namespace |
450 | |
451 | #if defined(DUMP_SUPPORT) |
452 | |
453 | const char *nfa_type_name(NFAEngineType type) { |
454 | return DISPATCH_BY_NFA_TYPE(type, getName, nullptr); |
455 | } |
456 | |
457 | string describe(const NFA &nfa) { |
458 | return DISPATCH_BY_NFA_TYPE((NFAEngineType)nfa.type, getDescription, &nfa); |
459 | } |
460 | |
461 | #endif /* DUMP_SUPPORT */ |
462 | |
463 | namespace { |
464 | template<NFAEngineType t> |
465 | struct getStateAlign { |
466 | static u32 call(void *) { |
467 | return NFATraits<t>::stateAlign; |
468 | } |
469 | }; |
470 | } |
471 | |
472 | u32 state_alignment(const NFA &nfa) { |
473 | return DISPATCH_BY_NFA_TYPE((NFAEngineType)nfa.type, getStateAlign, nullptr); |
474 | } |
475 | |
476 | namespace { |
477 | template<NFAEngineType t> |
478 | struct getFastness { |
479 | static u32 call(void *) { |
480 | return NFATraits<t>::fast; |
481 | } |
482 | }; |
483 | } |
484 | |
485 | bool is_fast(const NFA &nfa) { |
486 | NFAEngineType t = (NFAEngineType)nfa.type; |
487 | return DISPATCH_BY_NFA_TYPE(t, getFastness, nullptr); |
488 | } |
489 | |
490 | namespace { |
491 | template<NFAEngineType t> |
492 | struct is_limex { |
493 | static bool call(const void *) { |
494 | return NFATraits<t>::category == NFA_LIMEX; |
495 | } |
496 | }; |
497 | } |
498 | |
499 | namespace { |
500 | template<NFAEngineType t> |
501 | struct has_repeats_other_than_firsts_dispatch { |
502 | static nfa_dispatch_fn call(const void *) { |
503 | return NFATraits<t>::has_repeats_other_than_firsts; |
504 | } |
505 | }; |
506 | } |
507 | |
508 | bool has_bounded_repeats_other_than_firsts(const NFA &nfa) { |
509 | return DISPATCH_BY_NFA_TYPE((NFAEngineType)nfa.type, |
510 | has_repeats_other_than_firsts_dispatch, |
511 | &nfa)(&nfa); |
512 | } |
513 | |
514 | namespace { |
515 | template<NFAEngineType t> |
516 | struct has_repeats_dispatch { |
517 | static nfa_dispatch_fn call(const void *) { |
518 | return NFATraits<t>::has_repeats; |
519 | } |
520 | }; |
521 | } |
522 | |
523 | bool has_bounded_repeats(const NFA &nfa) { |
524 | return DISPATCH_BY_NFA_TYPE((NFAEngineType)nfa.type, has_repeats_dispatch, |
525 | &nfa)(&nfa); |
526 | } |
527 | |
528 | namespace { |
529 | template<NFAEngineType t> |
530 | struct has_accel_dispatch { |
531 | static nfa_dispatch_fn call(const void *) { |
532 | return NFATraits<t>::has_accel; |
533 | } |
534 | }; |
535 | } |
536 | |
537 | bool has_accel(const NFA &nfa) { |
538 | return DISPATCH_BY_NFA_TYPE((NFAEngineType)nfa.type, has_accel_dispatch, |
539 | &nfa)(&nfa); |
540 | } |
541 | |
542 | bool requires_decompress_key(const NFA &nfa) { |
543 | return DISPATCH_BY_NFA_TYPE((NFAEngineType)nfa.type, is_limex, &nfa); |
544 | } |
545 | |
546 | } // namespace ue2 |
547 | |