#ifndef ROSE_INTERNAL_H
#define ROSE_INTERNAL_H
#include "ue2common.h"
#include "rose_common.h"
#include "util/scatter.h"
#define ROSE_OFFSET_INVALID 0xffffffff
typedef u64a rose_group;
#define DELAY_BITS 5
#define DELAY_SLOT_COUNT (1U << DELAY_BITS)
#define MAX_DELAY (DELAY_SLOT_COUNT - 1)
#define DELAY_MASK (DELAY_SLOT_COUNT - 1)
struct RoseCountingMiracle {
char shufti;
u8 count;
u8 c;
u8 poison;
m128 lo;
m128 hi;
};
struct LeftNfaInfo {
u32 maxQueueLen;
u32 maxLag; u32 lagIndex; u32 stopTable; u8 transient;
char infix;
char eager;
char eod_check;
u32 countingMiracleOffset;
rose_group squash_mask;
};
struct NfaInfo {
u32 nfaOffset;
u32 stateOffset;
u32 fullStateOffset;
u32 ekeyListOffset;
u8 no_retrigger;
u8 in_sbmatcher;
u8 eod;
};
#define MAX_STORED_LEFTFIX_LAG 127
#define OWB_ZOMBIE_ALWAYS_YES 128
#define ROSE_STATE_OFFSET_STATUS_FLAGS 0
#define ROSE_STATE_OFFSET_ROLE_MMBIT sizeof(u8)
struct RoseStateOffsets {
u32 history;
u32 exhausted;
u32 exhausted_size;
u32 logicalVec;
u32 logicalVec_size;
u32 combVec;
u32 combVec_size;
u32 activeLeafArray;
u32 activeLeafArray_size;
u32 activeLeftArray;
u32 activeLeftArray_size;
u32 leftfixLagTable;
u32 anchorState;
u32 groups;
u32 groups_size;
u32 longLitState;
u32 longLitState_size;
u32 somLocation;
u32 somValid;
u32 somWritable;
u32 somMultibit_size;
u32 nfaStateBegin;
u32 end;
};
struct RoseBoundaryReports {
u32 reportEodOffset;
u32 reportZeroOffset;
u32 reportZeroEodOffset;
};
#define ROSE_RUNTIME_FULL_ROSE 0
#define ROSE_RUNTIME_PURE_LITERAL 1
#define ROSE_RUNTIME_SINGLE_OUTFIX 2
struct RoseEngine {
u8 pureLiteral;
u8 noFloatingRoots;
u8 requiresEodCheck;
u8 hasOutfixesInSmallBlock;
u8 runtimeImpl;
u8 mpvTriggeredByLeaf;
u8 canExhaust;
u8 hasSom;
u8 somHorizon;
u32 mode;
u32 historyRequired;
u32 ekeyCount;
u32 lkeyCount;
u32 lopCount;
u32 ckeyCount;
u32 logicalTreeOffset;
u32 combInfoMapOffset;
u32 dkeyCount;
u32 dkeyLogSize;
u32 invDkeyOffset;
u32 somLocationCount;
u32 somLocationFatbitSize;
u32 rolesWithStateCount; u32 stateSize;
u32 anchorStateSize;
u32 tStateSize;
u32 scratchStateSize;
u32 smallWriteOffset;
u32 amatcherOffset; u32 ematcherOffset; u32 fmatcherOffset; u32 drmatcherOffset; u32 sbmatcherOffset; u32 longLitTableOffset; u32 amatcherMinWidth;
u32 fmatcherMinWidth;
u32 eodmatcherMinWidth;
u32 amatcherMaxBiAnchoredWidth;
u32 fmatcherMaxBiAnchoredWidth;
u32 reportProgramOffset;
u32 reportProgramCount;
u32 delayProgramOffset;
u32 anchoredProgramOffset;
u32 activeArrayCount; u32 activeLeftCount; u32 queueCount;
u32 activeQueueArraySize;
u32 eagerIterOffset;
u32 handledKeyCount;
u32 handledKeyFatbitSize;
u32 leftOffset;
u32 roseCount;
u32 eodProgramOffset; u32 flushCombProgramOffset;
u32 lastFlushCombProgramOffset;
u32 lastByteHistoryIterOffset;
u32 minWidth;
u32 minWidthExcludingBoundaries;
u32 maxBiAnchoredWidth;
u32 anchoredDistance; u32 anchoredMinDistance;
u32 floatingDistance;
u32 floatingMinDistance;
u32 smallBlockDistance;
u32 floatingMinLiteralMatchOffset;
u32 nfaInfoOffset;
rose_group initialGroups;
rose_group floating_group_mask;
u32 size; u32 delay_count;
u32 delay_fatbit_size; u32 anchored_count;
u32 anchored_fatbit_size; u32 maxFloatingDelayedMatch;
u32 delayRebuildLength;
struct RoseStateOffsets stateOffsets;
struct RoseBoundaryReports boundary;
u32 totalNumLiterals;
u32 asize;
u32 outfixBeginQueue;
u32 outfixEndQueue;
u32 leftfixBeginQueue;
u32 initMpvNfa;
u32 rosePrefixCount;
u32 activeLeftIterOffset;
u32 ematcherRegionSize;
u32 somRevCount;
u32 somRevOffsetOffset;
u32 longLitStreamState;
struct scatter_full_plan state_init;
};
struct ALIGN_CL_DIRECTIVE anchored_matcher_info {
u32 next_offset;
u32 state_offset;
u32 anchoredMinDistance;
};
struct RoseLongLitSubtable {
u32 hashOffset;
u32 bloomOffset;
u8 hashBits;
u8 bloomBits;
u8 streamStateBits;
};
struct RoseLongLitTable {
u32 size;
struct RoseLongLitSubtable caseful;
struct RoseLongLitSubtable nocase;
u8 streamStateBytes;
u8 maxLen;
};
struct RoseLongLitHashEntry {
u32 str_offset;
u32 str_len;
};
static really_inline
const struct anchored_matcher_info *getALiteralMatcher(
const struct RoseEngine *t) {
if (!t->amatcherOffset) {
return NULL;
}
const char *lt = (const char *)t + t->amatcherOffset;
assert(ISALIGNED_CL(lt));
return (const struct anchored_matcher_info *)lt;
}
struct HWLM;
static really_inline
const struct HWLM *getFLiteralMatcher(const struct RoseEngine *t) {
if (!t->fmatcherOffset) {
return NULL;
}
const char *lt = (const char *)t + t->fmatcherOffset;
assert(ISALIGNED_CL(lt));
return (const struct HWLM *)lt;
}
static really_inline
const void *getSBLiteralMatcher(const struct RoseEngine *t) {
if (!t->sbmatcherOffset) {
return NULL;
}
const char *matcher = (const char *)t + t->sbmatcherOffset;
assert(ISALIGNED_N(matcher, 8));
return matcher;
}
static really_inline
const struct LeftNfaInfo *getLeftTable(const struct RoseEngine *t) {
const struct LeftNfaInfo *r
= (const struct LeftNfaInfo *)((const char *)t + t->leftOffset);
assert(ISALIGNED_N(r, 4));
return r;
}
struct mmbit_sparse_iter;
static really_inline
const struct mmbit_sparse_iter *getActiveLeftIter(const struct RoseEngine *t) {
assert(t->activeLeftIterOffset);
const struct mmbit_sparse_iter *it = (const struct mmbit_sparse_iter *)
((const char *)t + t->activeLeftIterOffset);
assert(ISALIGNED_N(it, 4));
return it;
}
static really_inline
const struct NfaInfo *getNfaInfoByQueue(const struct RoseEngine *t, u32 qi) {
const struct NfaInfo *infos
= (const struct NfaInfo *)((const char *)t + t->nfaInfoOffset);
assert(ISALIGNED_N(infos, sizeof(u32)));
return &infos[qi];
}
static really_inline
const struct NFA *getNfaByInfo(const struct RoseEngine *t,
const struct NfaInfo *info) {
return (const struct NFA *)((const char *)t + info->nfaOffset);
}
static really_inline
const struct NFA *getNfaByQueue(const struct RoseEngine *t, u32 qi) {
const struct NfaInfo *info = getNfaInfoByQueue(t, qi);
return getNfaByInfo(t, info);
}
static really_inline
u32 queueToLeftIndex(const struct RoseEngine *t, u32 qi) {
assert(qi >= t->leftfixBeginQueue);
return qi - t->leftfixBeginQueue;
}
static really_inline
const struct LeftNfaInfo *getLeftInfoByQueue(const struct RoseEngine *t,
u32 qi) {
const struct LeftNfaInfo *infos = getLeftTable(t);
return &infos[queueToLeftIndex(t, qi)];
}
struct SmallWriteEngine;
static really_inline
const struct SmallWriteEngine *getSmallWrite(const struct RoseEngine *t) {
if (!t->smallWriteOffset) {
return NULL;
}
const struct SmallWriteEngine *smwr =
(const struct SmallWriteEngine *)((const char *)t + t->smallWriteOffset);
return smwr;
}
#endif