Browse Source

[MERGE #4151 @dilijev] Code quality: Use enum classes in RegExp Bytecode

Merge pull request #4151 from dilijev:re-enumclass

Not a high priority to merge. Just wanted to get this off my plate.
Doug Ilijev 8 năm trước cách đây
mục cha
commit
762cd67d68

+ 1 - 1
lib/Backend/Lower.cpp

@@ -18672,7 +18672,7 @@ Lowerer::GenerateFastInlineRegExpExec(IR::Instr * instr)
         // We want the program's tag to be BOILiteral2Tag
         InsertCompareBranch(
             IR::IndirOpnd::New(opndProgram, (int32)UnifiedRegex::Program::GetOffsetOfTag(), TyUint8, m_func),
-            IR::IntConstOpnd::New(UnifiedRegex::Program::GetBOILiteral2Tag(), TyUint8, m_func),
+            IR::IntConstOpnd::New((IntConstType)UnifiedRegex::Program::GetBOILiteral2Tag(), TyUint8, m_func),
             Js::OpCode::BrNeq_A,
             labelFastHelper,
             instr);

+ 9 - 9
lib/Parser/RegexCompileTime.cpp

@@ -54,7 +54,7 @@ namespace UnifiedRegex
     }
 
 #define EMIT(compiler, T, ...) (new (compiler.Emit(sizeof(T))) T(__VA_ARGS__))
-#define L2I(O, label) LabelToInstPointer<O##Inst>(Inst::O, label)
+#define L2I(O, label) LabelToInstPointer<O##Inst>(Inst::InstTag::O, label)
 
     // Remember: The machine address of an instruction is no longer valid after a subsequent emit,
     //           so all label fixups must be done using Compiler::GetFixup / Compiler::DoFixup
@@ -4567,7 +4567,7 @@ namespace UnifiedRegex
 #endif
         )
     {
-        program->tag = Program::InstructionsTag;
+        program->tag = Program::ProgramTag::InstructionsTag;
         CaptureNoLiterals(program);
         EmitAndCaptureSuccInst(pattern->GetScriptContext()->GetRecycler(), program);
     }
@@ -4647,7 +4647,7 @@ namespace UnifiedRegex
                 {
                     program->rep.insts.litbuf = nullptr;
                     oi.InitializeTrigramInfo(scriptContext, pattern);
-                    program->tag = Program::OctoquadTag;
+                    program->tag = Program::ProgramTag::OctoquadTag;
                     program->rep.octoquad.matcher = OctoquadMatcher::New(scriptContext->GetRecycler(), standardChars, program->GetCaseMappingSource(), &oi);
                     compiled = true;
                 }
@@ -4664,29 +4664,29 @@ namespace UnifiedRegex
                 if (root->IsSingleChar(compiler, c))
                 {
                     // SPECIAL CASE: c
-                    program->tag = Program::SingleCharTag;
+                    program->tag = Program::ProgramTag::SingleCharTag;
                     program->rep.singleChar.c = c;
                 }
                 else if (root->IsBoundedWord(compiler))
                 {
                     // SPECIAL CASE: \b\w+\b
-                    program->tag = Program::BoundedWordTag;
+                    program->tag = Program::ProgramTag::BoundedWordTag;
                 }
                 else if (root->IsLeadingTrailingSpaces(compiler,
                     program->rep.leadingTrailingSpaces.beginMinMatch,
                     program->rep.leadingTrailingSpaces.endMinMatch))
                 {
                     // SPECIAL CASE: ^\s*|\s*$
-                    program->tag = Program::LeadingTrailingSpacesTag;
+                    program->tag = Program::ProgramTag::LeadingTrailingSpacesTag;
                 }
                 else if (root->IsBOILiteral2(compiler))
                 {
-                    program->tag = Program::BOILiteral2Tag;
+                    program->tag = Program::ProgramTag::BOILiteral2Tag;
                     program->rep.boiLiteral2.literal = *(DWORD *)litbuf;
                 }
                 else
                 {
-                    program->tag = Program::InstructionsTag;
+                    program->tag = Program::ProgramTag::InstructionsTag;
                     compiler.CaptureLiterals(root, litbuf);
 
                     root->AnnotatePass0(compiler);
@@ -4764,7 +4764,7 @@ namespace UnifiedRegex
             }
             else
             {
-                program->tag = Program::InstructionsTag;
+                program->tag = Program::ProgramTag::InstructionsTag;
                 compiler.CaptureLiterals(root, litbuf);
                 CharCount skipped = 0;
                 root->Emit(compiler, skipped);

+ 6 - 6
lib/Parser/RegexCompileTime.h

@@ -666,20 +666,20 @@ namespace UnifiedRegex
 
         void SetBOIInstructionsProgramTag()
         {
-            Assert(this->program->tag == Program::InstructionsTag
-                || this->program->tag == Program::BOIInstructionsTag);
+            Assert(this->program->tag == Program::ProgramTag::InstructionsTag
+                || this->program->tag == Program::ProgramTag::BOIInstructionsTag);
             Assert(this->CurrentLabel() == 0);
-            this->program->tag = Program::BOIInstructionsTag;
+            this->program->tag = Program::ProgramTag::BOIInstructionsTag;
         }
 
         void SetBOIInstructionsProgramForStickyFlagTag()
         {
-            Assert(this->program->tag == Program::InstructionsTag
-                || this->program->tag == Program::BOIInstructionsForStickyFlagTag);
+            Assert(this->program->tag == Program::ProgramTag::InstructionsTag
+                || this->program->tag == Program::ProgramTag::BOIInstructionsForStickyFlagTag);
             Assert(this->CurrentLabel() == 0);
             AssertMsg((this->program->flags & StickyRegexFlag) != 0, "Shouldn't set BOIInstructionsForStickyFlagTag, if sticky is false.");
 
-            this->program->tag = Program::BOIInstructionsForStickyFlagTag;
+            this->program->tag = Program::ProgramTag::BOIInstructionsForStickyFlagTag;
         }
 
         static void CaptureNoLiterals(Program* program);

+ 64 - 64
lib/Parser/RegexRuntime.cpp

@@ -34,7 +34,7 @@ namespace UnifiedRegex
 
 #define PUSH(contStack, T, ...) (new (contStack.Push<T>()) T(__VA_ARGS__))
 #define PUSHA(assertionStack, T, ...) (new (assertionStack.Push()) T(__VA_ARGS__))
-#define L2I(O, label) LabelToInstPointer<O##Inst>(Inst::O, label)
+#define L2I(O, label) LabelToInstPointer<O##Inst>(Inst::InstTag::O, label)
 
 #define FAIL_PARAMETERS input, inputOffset, instPointer, contStack, assertionStack, qcTicks
 #define HARDFAIL_PARAMETERS(mode) input, inputLength, matchStart, inputOffset, instPointer, contStack, assertionStack, qcTicks, mode
@@ -166,9 +166,9 @@ namespace UnifiedRegex
     {
         switch (mode)
         {
-        case BacktrackAndLater:
+        case HardFailMode::BacktrackAndLater:
             return Fail(FAIL_PARAMETERS);
-        case BacktrackOnly:
+        case HardFailMode::BacktrackOnly:
             if (Fail(FAIL_PARAMETERS))
             {
                 // No use trying any more start positions
@@ -179,7 +179,7 @@ namespace UnifiedRegex
             {
                 return false;
             }
-        case LaterOnly:
+        case HardFailMode::LaterOnly:
 #if ENABLE_REGEX_CONFIG_OPTIONS
             if (w != 0)
             {
@@ -189,7 +189,7 @@ namespace UnifiedRegex
             contStack.Clear();
             assertionStack.Clear();
             return true; // STOP EXECUTING
-        case ImmediateFail:
+        case HardFailMode::ImmediateFail:
             // No use trying any more start positions
             matchStart = inputLength;
             return true; // STOP EXECUTING
@@ -1252,9 +1252,9 @@ namespace UnifiedRegex
     // ----------------------------------------------------------------------
 
     template <>
-    BOITestInst<true>::BOITestInst() : Inst(BOIHardFailTest) {}
+    BOITestInst<true>::BOITestInst() : Inst(InstTag::BOIHardFailTest) {}
     template <>
-    BOITestInst<false>::BOITestInst() : Inst(BOITest) {}
+    BOITestInst<false>::BOITestInst() : Inst(InstTag::BOITest) {}
 
     template <bool canHardFail>
     inline bool BOITestInst<canHardFail>::Exec(REGEX_INST_EXEC_PARAMETERS) const
@@ -1264,7 +1264,7 @@ namespace UnifiedRegex
             if (canHardFail)
             {
                 // Clearly trying to start from later in the input won't help, and we know backtracking can't take us earlier in the input
-                return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+                return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
             }
             else
             {
@@ -1300,9 +1300,9 @@ namespace UnifiedRegex
     // ----------------------------------------------------------------------
 
     template <>
-    EOITestInst<true>::EOITestInst() : Inst(EOIHardFailTest) {}
+    EOITestInst<true>::EOITestInst() : Inst(InstTag::EOIHardFailTest) {}
     template <>
-    EOITestInst<false>::EOITestInst() : Inst(EOITest) {}
+    EOITestInst<false>::EOITestInst() : Inst(InstTag::EOITest) {}
 
     template <bool canHardFail>
     inline bool EOITestInst<canHardFail>::Exec(REGEX_INST_EXEC_PARAMETERS) const
@@ -1312,7 +1312,7 @@ namespace UnifiedRegex
             if (canHardFail)
             {
                 // We know backtracking can never take us later in the input, but starting from later in the input could help
-                return matcher.HardFail(HARDFAIL_PARAMETERS(LaterOnly));
+                return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::LaterOnly));
             }
             else
             {
@@ -1402,9 +1402,9 @@ namespace UnifiedRegex
     // ----------------------------------------------------------------------
 
     template <>
-    WordBoundaryTestInst<true>::WordBoundaryTestInst() : Inst(NegatedWordBoundaryTest) {}
+    WordBoundaryTestInst<true>::WordBoundaryTestInst() : Inst(InstTag::NegatedWordBoundaryTest) {}
     template <>
-    WordBoundaryTestInst<false>::WordBoundaryTestInst() : Inst(WordBoundaryTest) {}
+    WordBoundaryTestInst<false>::WordBoundaryTestInst() : Inst(InstTag::WordBoundaryTest) {}
 
     template <bool isNegation>
     inline bool WordBoundaryTestInst<isNegation>::Exec(REGEX_INST_EXEC_PARAMETERS) const
@@ -1931,7 +1931,7 @@ namespace UnifiedRegex
     {
         if (!this->Match(matcher, input, inputLength, inputOffset))
         {
-            return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+            return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
         }
 
         matchStart = inputOffset;
@@ -2026,7 +2026,7 @@ namespace UnifiedRegex
 
         if (inputOffset >= inputLength)
         {
-            return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+            return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
         }
 
         matchStart = inputOffset++;
@@ -2066,7 +2066,7 @@ namespace UnifiedRegex
 
         if (inputOffset >= inputLength)
         {
-            return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+            return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
         }
 
         matchStart = inputOffset++;
@@ -2106,7 +2106,7 @@ namespace UnifiedRegex
 
         if (inputOffset >= inputLength)
         {
-            return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+            return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
         }
 
         matchStart = inputOffset++;
@@ -2144,7 +2144,7 @@ namespace UnifiedRegex
     {
         if (!this->Match(matcher, input, inputLength, inputOffset))
         {
-            return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+            return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
         }
 
         matchStart = inputOffset;
@@ -2229,7 +2229,7 @@ namespace UnifiedRegex
         if (backup.lower > inputLength - matchStart)
         {
             // Even match at very end doesn't allow for minimum backup
-            return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+            return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
         }
 
         if (inputOffset < nextSyncInputOffset)
@@ -2257,7 +2257,7 @@ namespace UnifiedRegex
 
         if (inputOffset >= inputLength)
         {
-            return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+            return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
         }
 
         nextSyncInputOffset = inputOffset + 1;
@@ -2299,7 +2299,7 @@ namespace UnifiedRegex
         if (backup.lower > inputLength - matchStart)
         {
             // Even match at very end doesn't allow for minimum backup
-            return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+            return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
         }
 
         if (inputOffset < nextSyncInputOffset)
@@ -2327,7 +2327,7 @@ namespace UnifiedRegex
 
         if (inputOffset >= inputLength)
         {
-            return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+            return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
         }
 
         nextSyncInputOffset = inputOffset + 1;
@@ -2378,7 +2378,7 @@ namespace UnifiedRegex
         if (backup.lower > inputLength - matchStart)
         {
             // Even match at very end doesn't allow for minimum backup
-            return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+            return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
         }
 
         if(inputOffset < nextSyncInputOffset)
@@ -2397,7 +2397,7 @@ namespace UnifiedRegex
 
         if (!this->Match(matcher, input, inputLength, inputOffset))
         {
-            return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+            return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
         }
 
         nextSyncInputOffset = inputOffset + 1;
@@ -2503,7 +2503,7 @@ namespace UnifiedRegex
         if (backup.lower > inputLength - matchStart)
         {
             // Even match at very end doesn't allow for minimum backup
-            return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+            return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
         }
 
         if (inputOffset < nextSyncInputOffset)
@@ -2586,7 +2586,7 @@ namespace UnifiedRegex
         if (besti < 0)
         {
             // No literals matched
-            return matcher.HardFail(HARDFAIL_PARAMETERS(ImmediateFail));
+            return matcher.HardFail(HARDFAIL_PARAMETERS(HardFailMode::ImmediateFail));
         }
 
         nextSyncInputOffset = bestMatchOffset + 1;
@@ -3357,7 +3357,7 @@ namespace UnifiedRegex
                 // Since loop body is non-deterministic and does not define groups the rewind continuation must be on top of the stack.
                 Cont *top = contStack.Top();
                 Assert(top != 0);
-                Assert(top->tag == Cont::RewindLoopFixed);
+                Assert(top->tag == Cont::ContTag::RewindLoopFixed);
                 RewindLoopFixedCont* rewind = (RewindLoopFixedCont*)top;
                 rewind->tryingBody = false;
             }
@@ -3640,7 +3640,7 @@ namespace UnifiedRegex
                 // Since loop body is non-deterministic and does not define groups the rewind continuation must be on top of the stack.
                 Cont *top = contStack.Top();
                 Assert(top != 0);
-                Assert(top->tag == Cont::RewindLoopFixedGroupLastIteration);
+                Assert(top->tag == Cont::ContTag::RewindLoopFixedGroupLastIteration);
                 RewindLoopFixedGroupLastIterationCont* rewind = (RewindLoopFixedGroupLastIterationCont*)top;
                 rewind->tryingBody = false;
             }
@@ -3736,7 +3736,7 @@ namespace UnifiedRegex
             // Therefore we can simply update the Resume continuation still on the top of the stack with the current
             // input pointer.
             Cont* top = contStack.Top();
-            Assert(top != 0 && top->tag == Cont::Resume);
+            Assert(top != 0 && top->tag == Cont::ContTag::Resume);
             ResumeCont* resume = (ResumeCont*)top;
             resume->origInputOffset = inputOffset;
 
@@ -4508,7 +4508,7 @@ namespace UnifiedRegex
     // RestoreLoopCont
     // ----------------------------------------------------------------------
 
-    inline RestoreLoopCont::RestoreLoopCont(int loopId, LoopInfo& origLoopInfo, Matcher& matcher) : Cont(RestoreLoop), loopId(loopId)
+    inline RestoreLoopCont::RestoreLoopCont(int loopId, LoopInfo& origLoopInfo, Matcher& matcher) : Cont(ContTag::RestoreLoop), loopId(loopId)
     {
         this->origLoopInfo.number = origLoopInfo.number;
         this->origLoopInfo.startInputOffset = origLoopInfo.startInputOffset;
@@ -4959,14 +4959,14 @@ namespace UnifiedRegex
     }
 
 #if DBG
-    const uint32 contTags[] = {
-#define M(O) Cont::O,
+    const Cont::ContTag contTags[] = {
+#define M(O) Cont::ContTag::O,
 #include "RegexContcodes.h"
 #undef M
     };
 
-    const uint32 minContTag = contTags[0];
-    const uint32 maxContTag = contTags[(sizeof(contTags) / sizeof(uint32)) - 1];
+    const Cont::ContTag minContTag = contTags[0];
+    const Cont::ContTag maxContTag = contTags[(sizeof(contTags) / sizeof(Cont::ContTag)) - 1];
 #endif
 
     void Matcher::DoQueryContinue(const uint qcTicks)
@@ -5076,7 +5076,7 @@ namespace UnifiedRegex
             const Cont::ContTag tag = cont->tag;
             switch (tag)
             {
-#define M(O) case Cont::O: if (((O##Cont*)cont)->Exec(*this, input, inputOffset, instPointer, contStack, assertionStack, qcTicks)) return false; break;
+#define M(O) case Cont::ContTag::O: if (((O##Cont*)cont)->Exec(*this, input, inputOffset, instPointer, contStack, assertionStack, qcTicks)) return false; break;
 #include "RegexContcodes.h"
 #undef M
             default:
@@ -5088,16 +5088,16 @@ namespace UnifiedRegex
     }
 
 #if DBG
-    const uint32 instTags[] = {
-#define M(TagName) Inst::TagName,
+    const Inst::InstTag instTags[] = {
+#define M(TagName) Inst::InstTag::TagName,
 #define MTemplate(TagName, ...) M(TagName)
 #include "RegexOpCodes.h"
 #undef M
 #undef MTemplate
     };
 
-    const uint32 minInstTag = instTags[0];
-    const uint32 maxInstTag = instTags[(sizeof(instTags) / sizeof(uint32)) - 1];
+    const Inst::InstTag minInstTag = instTags[0];
+    const Inst::InstTag maxInstTag = instTags[(sizeof(instTags) / sizeof(Inst::InstTag)) - 1];
 #endif
 
     inline void Matcher::Run(const Char* const input, const CharCount inputLength, CharCount &matchStart, CharCount &nextSyncInputOffset, ContStack &contStack, AssertionStack &assertionStack, uint &qcTicks, bool firstIteration)
@@ -5123,7 +5123,7 @@ namespace UnifiedRegex
             switch (tag)
             {
 #define MBase(TagName, ClassName) \
-                case Inst::TagName: \
+                case Inst::InstTag::TagName: \
                     if (((const ClassName *)inst)->Exec(*this, input, inputLength, matchStart, inputOffset, nextSyncInputOffset, instPointer, contStack, assertionStack, qcTicks, firstIteration)) { return; } \
                     break;
 #define M(TagName) MBase(TagName, TagName##Inst)
@@ -5475,7 +5475,7 @@ namespace UnifiedRegex
         bool isStickyPresent = this->pattern->IsSticky();
         switch (prog->tag)
         {
-        case Program::BOIInstructionsTag:
+        case Program::ProgramTag::BOIInstructionsTag:
             if (offset != 0)
             {
                 groupInfos[0].Reset();
@@ -5485,14 +5485,14 @@ namespace UnifiedRegex
 
             // fall through
 
-        case Program::BOIInstructionsForStickyFlagTag:
-            AssertMsg(prog->tag == Program::BOIInstructionsTag || isStickyPresent, "prog->tag should be BOIInstructionsForStickyFlagTag if sticky = true.");
+        case Program::ProgramTag::BOIInstructionsForStickyFlagTag:
+            AssertMsg(prog->tag == Program::ProgramTag::BOIInstructionsTag || isStickyPresent, "prog->tag should be BOIInstructionsForStickyFlagTag if sticky = true.");
 
             loopMatchHere = false;
 
             // fall through
 
-        case Program::InstructionsTag:
+        case Program::ProgramTag::InstructionsTag:
             {
                 previousQcTime = 0;
                 uint qcTicks = 0;
@@ -5518,7 +5518,7 @@ namespace UnifiedRegex
                 break;
             }
 
-        case Program::SingleCharTag:
+        case Program::ProgramTag::SingleCharTag:
             if (this->pattern->IsIgnoreCase())
             {
                 res = MatchSingleCharCaseInsensitive(input, inputLength, offset, prog->rep.singleChar.c);
@@ -5530,19 +5530,19 @@ namespace UnifiedRegex
 
             break;
 
-        case Program::BoundedWordTag:
+        case Program::ProgramTag::BoundedWordTag:
             res = MatchBoundedWord(input, inputLength, offset);
             break;
 
-        case Program::LeadingTrailingSpacesTag:
+        case Program::ProgramTag::LeadingTrailingSpacesTag:
             res = MatchLeadingTrailingSpaces(input, inputLength, offset);
             break;
 
-        case Program::OctoquadTag:
+        case Program::ProgramTag::OctoquadTag:
             res = MatchOctoquad(input, inputLength, offset, prog->rep.octoquad.matcher);
             break;
 
-        case Program::BOILiteral2Tag:
+        case Program::ProgramTag::BOILiteral2Tag:
             res = MatchBOILiteral2(input, inputLength, offset, prog->rep.boiLiteral2.literal);
             break;
 
@@ -5592,7 +5592,7 @@ namespace UnifiedRegex
             }
             w->EOL();
         }
-        if (program->tag == Program::BOIInstructionsTag || program->tag == Program::InstructionsTag)
+        if (program->tag == Program::ProgramTag::BOIInstructionsTag || program->tag == Program::ProgramTag::InstructionsTag)
         {
             w->Print(_u("instPointer: "));
 
@@ -5600,7 +5600,7 @@ namespace UnifiedRegex
             switch (inst->tag)
             {
 #define MBase(TagName, ClassName) \
-            case Inst::TagName: \
+            case Inst::InstTag::TagName: \
             { \
                 const ClassName *actualInst = static_cast<const ClassName *>(inst); \
                 actualInst->Print(w, InstPointerToLabel(instPointer), program->rep.insts.litbuf); \
@@ -5661,7 +5661,7 @@ namespace UnifiedRegex
         , numGroups(0)
         , numLoops(0)
     {
-        tag = InstructionsTag;
+        tag = ProgramTag::InstructionsTag;
         rep.insts.insts = nullptr;
         rep.insts.instsLen = 0;
         rep.insts.litbuf = nullptr;
@@ -5676,7 +5676,7 @@ namespace UnifiedRegex
 
     Field(ScannerInfo *)*Program::CreateScannerArrayForSyncToLiterals(Recycler *const recycler)
     {
-        Assert(tag == InstructionsTag);
+        Assert(tag == ProgramTag::InstructionsTag);
         Assert(!rep.insts.scannersForSyncToLiterals);
         Assert(recycler);
 
@@ -5692,7 +5692,7 @@ namespace UnifiedRegex
         const CharCount length,
         const bool isEquivClass)
     {
-        Assert(tag == InstructionsTag);
+        Assert(tag == ProgramTag::InstructionsTag);
         Assert(rep.insts.scannersForSyncToLiterals);
         Assert(recycler);
         Assert(scannerIndex >= 0);
@@ -5706,7 +5706,7 @@ namespace UnifiedRegex
 
     void Program::FreeBody(ArenaAllocator* rtAllocator)
     {
-        if (tag != InstructionsTag || !rep.insts.insts)
+        if (tag != ProgramTag::InstructionsTag || !rep.insts.insts)
         {
             return;
         }
@@ -5719,7 +5719,7 @@ namespace UnifiedRegex
             switch(inst->tag)
             {
 #define MBase(TagName, ClassName) \
-                case Inst::TagName: \
+                case Inst::InstTag::TagName: \
                 { \
                     const auto actualInst = static_cast<ClassName *>(inst); \
                     actualInst->FreeBody(rtAllocator); \
@@ -5763,12 +5763,12 @@ namespace UnifiedRegex
         w->PrintEOL(_u("numLoops:     %d"), numLoops);
         switch (tag)
         {
-        case BOIInstructionsTag:
-        case InstructionsTag:
+        case ProgramTag::BOIInstructionsTag:
+        case ProgramTag::InstructionsTag:
             {
                 w->PrintEOL(_u("instructions: {"));
                 w->Indent();
-                if (tag == BOIInstructionsTag)
+                if (tag == ProgramTag::BOIInstructionsTag)
                 {
                     w->PrintEOL(_u("       BOITest(hardFail: true)"));
                 }
@@ -5781,7 +5781,7 @@ namespace UnifiedRegex
                     switch (inst->tag)
                     {
 #define MBase(TagName, ClassName) \
-                    case Inst::TagName: \
+                    case Inst::InstTag::TagName: \
                     { \
                         const ClassName *actualInst = static_cast<const ClassName *>(inst); \
                         curr += actualInst->Print(w, (Label)(isBaselineMode ? i++ : curr - rep.insts.insts), rep.insts.litbuf); \
@@ -5802,19 +5802,19 @@ namespace UnifiedRegex
                 w->PrintEOL(_u("}"));
             }
             break;
-        case SingleCharTag:
+        case ProgramTag::SingleCharTag:
             w->Print(_u("special form: <match single char "));
             w->PrintQuotedChar(rep.singleChar.c);
             w->PrintEOL(_u(">"));
             break;
-        case BoundedWordTag:
+        case ProgramTag::BoundedWordTag:
             w->PrintEOL(_u("special form: <match bounded word>"));
             break;
-        case LeadingTrailingSpacesTag:
+        case ProgramTag::LeadingTrailingSpacesTag:
             w->PrintEOL(_u("special form: <match leading/trailing spaces: minBegin=%d minEnd=%d>"),
                 rep.leadingTrailingSpaces.beginMinMatch, rep.leadingTrailingSpaces.endMinMatch);
             break;
-        case OctoquadTag:
+        case ProgramTag::OctoquadTag:
             w->Print(_u("special form: <octoquad "));
             rep.octoquad.matcher->Print(w);
             w->PrintEOL(_u(">"));

+ 92 - 91
lib/Parser/RegexRuntime.h

@@ -30,6 +30,7 @@ namespace UnifiedRegex
 
     struct Program : private Chars<char16>
     {
+        friend class Lowerer;
         friend class Compiler;
         friend struct MatchLiteralNode;
         friend struct AltNode;
@@ -64,7 +65,7 @@ namespace UnifiedRegex
         Field(RegexFlags) flags;
 
     private:
-        enum ProgramTag : uint8
+        enum class ProgramTag : uint8
         {
             InstructionsTag,
             BOIInstructionsTag,
@@ -698,7 +699,7 @@ namespace UnifiedRegex
 
     struct Inst : protected Chars<char16>
     {
-        enum InstTag : uint8
+        enum class InstTag : uint8
         {
 #define M(TagName) TagName,
 #define MTemplate(TagName, ...) M(TagName)
@@ -744,21 +745,21 @@ namespace UnifiedRegex
 
     struct NopInst : Inst
     {
-        inline NopInst() : Inst(Nop) {}
+        inline NopInst() : Inst(InstTag::Nop) {}
 
         INST_BODY
     };
 
     struct FailInst : Inst
     {
-        inline FailInst() : Inst(Fail) {}
+        inline FailInst() : Inst(InstTag::Fail) {}
 
         INST_BODY
     };
 
     struct SuccInst : Inst
     {
-        inline SuccInst() : Inst(Succ) {}
+        inline SuccInst() : Inst(InstTag::Succ) {}
 
         INST_BODY
     };
@@ -766,7 +767,7 @@ namespace UnifiedRegex
     struct JumpInst : Inst, JumpMixin
     {
         // targetLabel must always be fixed up
-        inline JumpInst() : Inst(Jump), JumpMixin() {}
+        inline JumpInst() : Inst(InstTag::Jump), JumpMixin() {}
 
         INST_BODY
     };
@@ -774,7 +775,7 @@ namespace UnifiedRegex
     struct JumpIfNotCharInst : Inst, CharMixin, JumpMixin
     {
         // targetLabel must always be fixed up
-        inline JumpIfNotCharInst(Char c) : Inst(JumpIfNotChar), CharMixin(c), JumpMixin() {}
+        inline JumpIfNotCharInst(Char c) : Inst(InstTag::JumpIfNotChar), CharMixin(c), JumpMixin() {}
 
         INST_BODY
     };
@@ -782,7 +783,7 @@ namespace UnifiedRegex
     struct MatchCharOrJumpInst : Inst, CharMixin, JumpMixin
     {
         // targetLabel must always be fixed up
-        inline MatchCharOrJumpInst(Char c) : Inst(MatchCharOrJump), CharMixin(c), JumpMixin() {}
+        inline MatchCharOrJumpInst(Char c) : Inst(InstTag::MatchCharOrJump), CharMixin(c), JumpMixin() {}
 
         INST_BODY
     };
@@ -791,7 +792,7 @@ namespace UnifiedRegex
     {
         // set must always be cloned from source
         // targetLabel must always be fixed up
-        inline JumpIfNotSetInst() : Inst(JumpIfNotSet), JumpMixin() {}
+        inline JumpIfNotSetInst() : Inst(InstTag::JumpIfNotSet), JumpMixin() {}
 
         INST_BODY
         INST_BODY_FREE(SetMixin<false>)
@@ -801,7 +802,7 @@ namespace UnifiedRegex
     {
         // set must always be cloned from source
         // targetLabel must always be fixed up
-        inline MatchSetOrJumpInst() : Inst(MatchSetOrJump), JumpMixin() {}
+        inline MatchSetOrJumpInst() : Inst(InstTag::MatchSetOrJump), JumpMixin() {}
 
         INST_BODY
         INST_BODY_FREE(SetMixin<false>)
@@ -810,7 +811,7 @@ namespace UnifiedRegex
 #define SwitchInstActual(n)                                                 \
     struct Switch##n##Inst : Inst, SwitchMixin<n>                           \
     {                                                                       \
-        inline Switch##n##Inst() : Inst(Switch##n), SwitchMixin() {}        \
+        inline Switch##n##Inst() : Inst(InstTag::Switch##n), SwitchMixin() {}        \
         INST_BODY                                                           \
     };
     SwitchInstActual(2);
@@ -823,7 +824,7 @@ namespace UnifiedRegex
 #define SwitchAndConsumeInstActual(n)                                                            \
     struct SwitchAndConsume##n##Inst : Inst, SwitchMixin<n>                                     \
     {                                                                                           \
-        inline SwitchAndConsume##n##Inst() : Inst(SwitchAndConsume##n), SwitchMixin() {}        \
+        inline SwitchAndConsume##n##Inst() : Inst(InstTag::SwitchAndConsume##n), SwitchMixin() {}        \
         INST_BODY                                                                               \
     };
     SwitchAndConsumeInstActual(2);
@@ -858,7 +859,7 @@ namespace UnifiedRegex
     // BOL = Beginning of Line (/^.../)
     struct BOLTestInst : Inst
     {
-        inline BOLTestInst() : Inst(BOLTest) {}
+        inline BOLTestInst() : Inst(InstTag::BOLTest) {}
 
         INST_BODY
     };
@@ -866,7 +867,7 @@ namespace UnifiedRegex
     // EOL = End of Line (/...$/)
     struct EOLTestInst : Inst
     {
-        inline EOLTestInst() : Inst(EOLTest) {}
+        inline EOLTestInst() : Inst(InstTag::EOLTest) {}
 
         INST_BODY
     };
@@ -885,14 +886,14 @@ namespace UnifiedRegex
 
     struct MatchCharInst : Inst, CharMixin
     {
-        inline MatchCharInst(Char c) : Inst(MatchChar), CharMixin(c) {}
+        inline MatchCharInst(Char c) : Inst(InstTag::MatchChar), CharMixin(c) {}
 
         INST_BODY
     };
 
     struct MatchChar2Inst : Inst, Char2Mixin
     {
-        inline MatchChar2Inst(Char c0, Char c1) : Inst(MatchChar2), Char2Mixin(c0, c1) {}
+        inline MatchChar2Inst(Char c0, Char c1) : Inst(InstTag::MatchChar2), Char2Mixin(c0, c1) {}
 
         INST_BODY
     };
@@ -900,14 +901,14 @@ namespace UnifiedRegex
 
     struct MatchChar3Inst : Inst, Char3Mixin
     {
-        inline MatchChar3Inst(Char c0, Char c1, Char c2) : Inst(MatchChar3), Char3Mixin(c0, c1, c2) {}
+        inline MatchChar3Inst(Char c0, Char c1, Char c2) : Inst(InstTag::MatchChar3), Char3Mixin(c0, c1, c2) {}
 
         INST_BODY
     };
 
     struct MatchChar4Inst : Inst, Char4Mixin
     {
-        inline MatchChar4Inst(Char c0, Char c1, Char c2, Char c3) : Inst(MatchChar4), Char4Mixin(c0, c1, c2, c3) {}
+        inline MatchChar4Inst(Char c0, Char c1, Char c2, Char c3) : Inst(InstTag::MatchChar4), Char4Mixin(c0, c1, c2, c3) {}
 
         INST_BODY
     };
@@ -916,7 +917,7 @@ namespace UnifiedRegex
     struct MatchSetInst : Inst, SetMixin<IsNegation>
     {
         // set must always be cloned from source
-        inline MatchSetInst() : Inst(IsNegation ? MatchNegatedSet : MatchSet) {}
+        inline MatchSetInst() : Inst(IsNegation ? InstTag::MatchNegatedSet : InstTag::MatchSet) {}
 
         INST_BODY
         INST_BODY_FREE(SetMixin<IsNegation>)
@@ -924,14 +925,14 @@ namespace UnifiedRegex
 
     struct MatchLiteralInst : Inst, LiteralMixin
     {
-        inline MatchLiteralInst(CharCount offset, CharCount length) : Inst(MatchLiteral), LiteralMixin(offset, length) {}
+        inline MatchLiteralInst(CharCount offset, CharCount length) : Inst(InstTag::MatchLiteral), LiteralMixin(offset, length) {}
 
         INST_BODY
     };
 
     struct MatchLiteralEquivInst : Inst, LiteralMixin
     {
-        inline MatchLiteralEquivInst(CharCount offset, CharCount length) : Inst(MatchLiteralEquiv), LiteralMixin(offset, length) {}
+        inline MatchLiteralEquivInst(CharCount offset, CharCount length) : Inst(InstTag::MatchLiteralEquiv), LiteralMixin(offset, length) {}
 
         INST_BODY
     };
@@ -939,7 +940,7 @@ namespace UnifiedRegex
     struct MatchTrieInst : Inst, TrieMixin
     {
         // Trie must always be cloned
-        inline MatchTrieInst() : Inst(MatchTrie) {}
+        inline MatchTrieInst() : Inst(InstTag::MatchTrie) {}
         void FreeBody(ArenaAllocator* rtAllocator);
 
         INST_BODY
@@ -947,7 +948,7 @@ namespace UnifiedRegex
 
     struct OptMatchCharInst : Inst, CharMixin
     {
-        inline OptMatchCharInst(Char c) : Inst(OptMatchChar), CharMixin(c) {}
+        inline OptMatchCharInst(Char c) : Inst(InstTag::OptMatchChar), CharMixin(c) {}
 
         INST_BODY
     };
@@ -955,7 +956,7 @@ namespace UnifiedRegex
     struct OptMatchSetInst : Inst, SetMixin<false>
     {
         // set must always be cloned from source
-        inline OptMatchSetInst() : Inst(OptMatchSet) {}
+        inline OptMatchSetInst() : Inst(InstTag::OptMatchSet) {}
 
         INST_BODY
         INST_BODY_FREE(SetMixin<false>)
@@ -968,14 +969,14 @@ namespace UnifiedRegex
 
     struct SyncToCharAndContinueInst : Inst, CharMixin
     {
-        inline SyncToCharAndContinueInst(Char c) : Inst(SyncToCharAndContinue), CharMixin(c) {}
+        inline SyncToCharAndContinueInst(Char c) : Inst(InstTag::SyncToCharAndContinue), CharMixin(c) {}
 
         INST_BODY
     };
 
     struct SyncToChar2SetAndContinueInst : Inst, Char2Mixin
     {
-        inline SyncToChar2SetAndContinueInst(Char c0, Char c1) : Inst(SyncToChar2SetAndContinue), Char2Mixin(c0, c1) {}
+        inline SyncToChar2SetAndContinueInst(Char c0, Char c1) : Inst(InstTag::SyncToChar2SetAndContinue), Char2Mixin(c0, c1) {}
 
         INST_BODY
     };
@@ -984,7 +985,7 @@ namespace UnifiedRegex
     struct SyncToSetAndContinueInst : Inst, SetMixin<IsNegation>
     {
         // set must always be cloned from source
-        inline SyncToSetAndContinueInst() : Inst(IsNegation ? SyncToNegatedSetAndContinue : SyncToSetAndContinue) {}
+        inline SyncToSetAndContinueInst() : Inst(IsNegation ? InstTag::SyncToNegatedSetAndContinue : InstTag::SyncToSetAndContinue) {}
 
         INST_BODY
         INST_BODY_FREE(SetMixin<IsNegation>)
@@ -1002,14 +1003,14 @@ namespace UnifiedRegex
     struct SyncToChar2LiteralAndContinueInst : SyncToLiteralAndContinueInstT<Char2LiteralScannerMixin>
     {
         SyncToChar2LiteralAndContinueInst(Char c0, Char c1) :
-            SyncToLiteralAndContinueInstT(SyncToChar2LiteralAndContinue, 0, 2) { Char2LiteralScannerMixin::Setup(c0, c1); }
+            SyncToLiteralAndContinueInstT(InstTag::SyncToChar2LiteralAndContinue, 0, 2) { Char2LiteralScannerMixin::Setup(c0, c1); }
     };
 
     struct SyncToLiteralAndContinueInst : SyncToLiteralAndContinueInstT<ScannerMixin>
     {
         // scanner must be setup
         SyncToLiteralAndContinueInst(CharCount offset, CharCount length) :
-            SyncToLiteralAndContinueInstT(SyncToLiteralAndContinue, offset, length) {}
+            SyncToLiteralAndContinueInstT(InstTag::SyncToLiteralAndContinue, offset, length) {}
 
         INST_BODY_FREE(ScannerMixin)
     };
@@ -1018,7 +1019,7 @@ namespace UnifiedRegex
     {
         // scanner must be setup
         SyncToLinearLiteralAndContinueInst(CharCount offset, CharCount length) :
-            SyncToLiteralAndContinueInstT(SyncToLinearLiteralAndContinue, offset, length) {}
+            SyncToLiteralAndContinueInstT(InstTag::SyncToLinearLiteralAndContinue, offset, length) {}
 
         INST_BODY_FREE(ScannerMixin_WithLinearCharMap)
     };
@@ -1027,7 +1028,7 @@ namespace UnifiedRegex
     {
         // scanner must be setup
         SyncToLiteralEquivAndContinueInst(CharCount offset, CharCount length) :
-            SyncToLiteralAndContinueInstT(SyncToLiteralEquivAndContinue, offset, length) {}
+            SyncToLiteralAndContinueInstT(InstTag::SyncToLiteralEquivAndContinue, offset, length) {}
 
         INST_BODY_FREE(EquivScannerMixin)
     };
@@ -1036,21 +1037,21 @@ namespace UnifiedRegex
     {
         // scanner must be setup
         SyncToLiteralEquivTrivialLastPatCharAndContinueInst(CharCount offset, CharCount length) :
-            SyncToLiteralAndContinueInstT(SyncToLiteralEquivTrivialLastPatCharAndContinue, offset, length) {}
+            SyncToLiteralAndContinueInstT(InstTag::SyncToLiteralEquivTrivialLastPatCharAndContinue, offset, length) {}
 
         INST_BODY_FREE(EquivTrivialLastPatCharScannerMixin)
     };
 
     struct SyncToCharAndConsumeInst : Inst, CharMixin
     {
-        inline SyncToCharAndConsumeInst(Char c) : Inst(SyncToCharAndConsume), CharMixin(c) {}
+        inline SyncToCharAndConsumeInst(Char c) : Inst(InstTag::SyncToCharAndConsume), CharMixin(c) {}
 
         INST_BODY
     };
 
     struct SyncToChar2SetAndConsumeInst : Inst, Char2Mixin
     {
-        inline SyncToChar2SetAndConsumeInst(Char c0, Char c1) : Inst(SyncToChar2SetAndConsume), Char2Mixin(c0, c1) {}
+        inline SyncToChar2SetAndConsumeInst(Char c0, Char c1) : Inst(InstTag::SyncToChar2SetAndConsume), Char2Mixin(c0, c1) {}
 
         INST_BODY
     };
@@ -1059,7 +1060,7 @@ namespace UnifiedRegex
     struct SyncToSetAndConsumeInst : Inst, SetMixin<IsNegation>
     {
         // set must always be cloned from source
-        inline SyncToSetAndConsumeInst() : Inst(IsNegation ? SyncToNegatedSetAndConsume : SyncToSetAndConsume) {}
+        inline SyncToSetAndConsumeInst() : Inst(IsNegation ? InstTag::SyncToNegatedSetAndConsume : InstTag::SyncToSetAndConsume) {}
 
         INST_BODY
         INST_BODY_FREE(SetMixin<IsNegation>)
@@ -1077,14 +1078,14 @@ namespace UnifiedRegex
     struct SyncToChar2LiteralAndConsumeInst : SyncToLiteralAndConsumeInstT<Char2LiteralScannerMixin>
     {
         SyncToChar2LiteralAndConsumeInst(Char c0, Char c1) :
-            SyncToLiteralAndConsumeInstT(SyncToChar2LiteralAndConsume, 0, 2) { Char2LiteralScannerMixin::Setup(c0, c1); }
+            SyncToLiteralAndConsumeInstT(InstTag::SyncToChar2LiteralAndConsume, 0, 2) { Char2LiteralScannerMixin::Setup(c0, c1); }
     };
 
     struct SyncToLiteralAndConsumeInst : SyncToLiteralAndConsumeInstT<ScannerMixin>
     {
         // scanner must be setup
         SyncToLiteralAndConsumeInst(CharCount offset, CharCount length) :
-            SyncToLiteralAndConsumeInstT(SyncToLiteralAndConsume, offset, length) {}
+            SyncToLiteralAndConsumeInstT(InstTag::SyncToLiteralAndConsume, offset, length) {}
 
         INST_BODY_FREE(ScannerMixin)
     };
@@ -1093,7 +1094,7 @@ namespace UnifiedRegex
     {
         // scanner must be setup
         SyncToLinearLiteralAndConsumeInst(CharCount offset, CharCount length) :
-            SyncToLiteralAndConsumeInstT(SyncToLinearLiteralAndConsume, offset, length) {}
+            SyncToLiteralAndConsumeInstT(InstTag::SyncToLinearLiteralAndConsume, offset, length) {}
 
         INST_BODY_FREE(ScannerMixin_WithLinearCharMap)
     };
@@ -1102,7 +1103,7 @@ namespace UnifiedRegex
     {
         // scanner must be setup
         SyncToLiteralEquivAndConsumeInst(CharCount offset, CharCount length) :
-            SyncToLiteralAndConsumeInstT(SyncToLiteralEquivAndConsume,offset, length) {}
+            SyncToLiteralAndConsumeInstT(InstTag::SyncToLiteralEquivAndConsume,offset, length) {}
 
         INST_BODY_FREE(EquivScannerMixin)
     };
@@ -1111,14 +1112,14 @@ namespace UnifiedRegex
     {
         // scanner must be setup
         SyncToLiteralEquivTrivialLastPatCharAndConsumeInst(CharCount offset, CharCount length) :
-            SyncToLiteralAndConsumeInstT(SyncToLiteralEquivTrivialLastPatCharAndConsume, offset, length) {}
+            SyncToLiteralAndConsumeInstT(InstTag::SyncToLiteralEquivTrivialLastPatCharAndConsume, offset, length) {}
 
         INST_BODY_FREE(EquivTrivialLastPatCharScannerMixin)
     };
 
     struct SyncToCharAndBackupInst : Inst, CharMixin, BackupMixin
     {
-        inline SyncToCharAndBackupInst(Char c, const CountDomain& backup) : Inst(SyncToCharAndBackup), CharMixin(c), BackupMixin(backup) {}
+        inline SyncToCharAndBackupInst(Char c, const CountDomain& backup) : Inst(InstTag::SyncToCharAndBackup), CharMixin(c), BackupMixin(backup) {}
 
         INST_BODY
     };
@@ -1127,7 +1128,7 @@ namespace UnifiedRegex
     struct SyncToSetAndBackupInst : Inst, SetMixin<IsNegation>, BackupMixin
     {
         // set must always be cloned from source
-        inline SyncToSetAndBackupInst(const CountDomain& backup) : Inst(IsNegation ? SyncToNegatedSetAndBackup : SyncToSetAndBackup), BackupMixin(backup) {}
+        inline SyncToSetAndBackupInst(const CountDomain& backup) : Inst(IsNegation ? InstTag::SyncToNegatedSetAndBackup : InstTag::SyncToSetAndBackup), BackupMixin(backup) {}
 
         INST_BODY
         INST_BODY_FREE(SetMixin<IsNegation>)
@@ -1145,14 +1146,14 @@ namespace UnifiedRegex
     struct SyncToChar2LiteralAndBackupInst : SyncToLiteralAndBackupInstT<Char2LiteralScannerMixin>
     {
         SyncToChar2LiteralAndBackupInst(Char c0, Char c1, const CountDomain& backup) :
-            SyncToLiteralAndBackupInstT(SyncToChar2LiteralAndBackup, 0, 2, backup) { Char2LiteralScannerMixin::Setup(c0, c1); }
+            SyncToLiteralAndBackupInstT(InstTag::SyncToChar2LiteralAndBackup, 0, 2, backup) { Char2LiteralScannerMixin::Setup(c0, c1); }
     };
 
     struct SyncToLiteralAndBackupInst : SyncToLiteralAndBackupInstT<ScannerMixin>
     {
         // scanner must be setup
         SyncToLiteralAndBackupInst(CharCount offset, CharCount length, const CountDomain& backup) :
-            SyncToLiteralAndBackupInstT(SyncToLiteralAndBackup, offset, length, backup) {}
+            SyncToLiteralAndBackupInstT(InstTag::SyncToLiteralAndBackup, offset, length, backup) {}
 
         INST_BODY_FREE(ScannerMixin)
     };
@@ -1161,7 +1162,7 @@ namespace UnifiedRegex
     {
         // scanner must be setup
         SyncToLinearLiteralAndBackupInst(CharCount offset, CharCount length, const CountDomain& backup) :
-            SyncToLiteralAndBackupInstT(SyncToLinearLiteralAndBackup, offset, length, backup) {}
+            SyncToLiteralAndBackupInstT(InstTag::SyncToLinearLiteralAndBackup, offset, length, backup) {}
 
         INST_BODY_FREE(ScannerMixin_WithLinearCharMap)
     };
@@ -1170,7 +1171,7 @@ namespace UnifiedRegex
     {
         // scanner must be setup
          SyncToLiteralEquivAndBackupInst(CharCount offset, CharCount length, const CountDomain& backup) :
-             SyncToLiteralAndBackupInstT(SyncToLiteralEquivAndBackup, offset, length, backup) {}
+             SyncToLiteralAndBackupInstT(InstTag::SyncToLiteralEquivAndBackup, offset, length, backup) {}
 
         INST_BODY_FREE(EquivScannerMixin)
     };
@@ -1179,7 +1180,7 @@ namespace UnifiedRegex
     {
         // scanner must be setup
          SyncToLiteralEquivTrivialLastPatCharAndBackupInst(CharCount offset, CharCount length, const CountDomain& backup) :
-             SyncToLiteralAndBackupInstT(SyncToLiteralEquivTrivialLastPatCharAndBackup, offset, length, backup) {}
+             SyncToLiteralAndBackupInstT(InstTag::SyncToLiteralEquivTrivialLastPatCharAndBackup, offset, length, backup) {}
 
         INST_BODY_FREE(EquivTrivialLastPatCharScannerMixin)
     };
@@ -1188,7 +1189,7 @@ namespace UnifiedRegex
     {
         // scanner mixins must be setup
         inline SyncToLiteralsAndBackupInst(Recycler *recycler, Program *program, const CountDomain& backup)
-            : Inst(SyncToLiteralsAndBackup), ScannersMixin(recycler, program), BackupMixin(backup)
+            : Inst(InstTag::SyncToLiteralsAndBackup), ScannersMixin(recycler, program), BackupMixin(backup)
         {
         }
 
@@ -1202,14 +1203,14 @@ namespace UnifiedRegex
 
     struct MatchGroupInst : Inst, GroupMixin
     {
-        inline MatchGroupInst(int groupId) : Inst(MatchGroup), GroupMixin(groupId) {}
+        inline MatchGroupInst(int groupId) : Inst(InstTag::MatchGroup), GroupMixin(groupId) {}
 
         INST_BODY
     };
 
     struct BeginDefineGroupInst : Inst, GroupMixin
     {
-        inline BeginDefineGroupInst(int groupId) : Inst(BeginDefineGroup), GroupMixin(groupId) {}
+        inline BeginDefineGroupInst(int groupId) : Inst(InstTag::BeginDefineGroup), GroupMixin(groupId) {}
 
         INST_BODY
     };
@@ -1217,7 +1218,7 @@ namespace UnifiedRegex
     struct EndDefineGroupInst : Inst, GroupMixin, NoNeedToSaveMixin
     {
         inline EndDefineGroupInst(int groupId, bool noNeedToSave)
-            : Inst(EndDefineGroup), GroupMixin(groupId), NoNeedToSaveMixin(noNeedToSave)
+            : Inst(InstTag::EndDefineGroup), GroupMixin(groupId), NoNeedToSaveMixin(noNeedToSave)
         {
         }
 
@@ -1226,7 +1227,7 @@ namespace UnifiedRegex
 
     struct DefineGroupFixedInst : Inst, GroupMixin, FixedLengthMixin, NoNeedToSaveMixin
     {
-        inline DefineGroupFixedInst(int groupId, CharCount length, bool noNeedToSave) : Inst(DefineGroupFixed), GroupMixin(groupId), FixedLengthMixin(length), NoNeedToSaveMixin(noNeedToSave) {}
+        inline DefineGroupFixedInst(int groupId, CharCount length, bool noNeedToSave) : Inst(InstTag::DefineGroupFixed), GroupMixin(groupId), FixedLengthMixin(length), NoNeedToSaveMixin(noNeedToSave) {}
 
         INST_BODY
     };
@@ -1239,7 +1240,7 @@ namespace UnifiedRegex
     {
         // exitLabel must always be fixed up
         inline BeginLoopInst(int loopId, const CountDomain& repeats, bool hasOuterLoops, bool hasInnerNondet, int minBodyGroupId, int maxBodyGroupId, bool isGreedy)
-            : Inst(BeginLoop), BeginLoopMixin(loopId, repeats, hasOuterLoops, hasInnerNondet), BodyGroupsMixin(minBodyGroupId, maxBodyGroupId), GreedyMixin(isGreedy)
+            : Inst(InstTag::BeginLoop), BeginLoopMixin(loopId, repeats, hasOuterLoops, hasInnerNondet), BodyGroupsMixin(minBodyGroupId, maxBodyGroupId), GreedyMixin(isGreedy)
         {}
 
         INST_BODY
@@ -1247,7 +1248,7 @@ namespace UnifiedRegex
 
     struct RepeatLoopInst : Inst, RepeatLoopMixin
     {
-        inline RepeatLoopInst(Label beginLabel) : Inst(RepeatLoop), RepeatLoopMixin(beginLabel) {}
+        inline RepeatLoopInst(Label beginLabel) : Inst(InstTag::RepeatLoop), RepeatLoopMixin(beginLabel) {}
 
         INST_BODY
     };
@@ -1256,7 +1257,7 @@ namespace UnifiedRegex
     {
         // exitLabel must always be fixed up
         inline BeginLoopIfCharInst(Char c, int loopId, const CountDomain& repeats, bool hasOuterLoops, bool hasInnerNondet, int minBodyGroupId, int maxBodyGroupId)
-            : Inst(BeginLoopIfChar), CharMixin(c), BeginLoopMixin(loopId, repeats, hasOuterLoops, hasInnerNondet), BodyGroupsMixin(minBodyGroupId, maxBodyGroupId) {}
+            : Inst(InstTag::BeginLoopIfChar), CharMixin(c), BeginLoopMixin(loopId, repeats, hasOuterLoops, hasInnerNondet), BodyGroupsMixin(minBodyGroupId, maxBodyGroupId) {}
 
         INST_BODY
     };
@@ -1266,7 +1267,7 @@ namespace UnifiedRegex
         // set must always be cloned from source
         // exitLabel must always be fixed up
         inline BeginLoopIfSetInst(int loopId, const CountDomain& repeats, bool hasOuterLoops, bool hasInnerNondet, int minBodyGroupId, int maxBodyGroupId)
-            : Inst(BeginLoopIfSet), BeginLoopMixin(loopId, repeats, hasOuterLoops, hasInnerNondet), BodyGroupsMixin(minBodyGroupId, maxBodyGroupId) {}
+            : Inst(InstTag::BeginLoopIfSet), BeginLoopMixin(loopId, repeats, hasOuterLoops, hasInnerNondet), BodyGroupsMixin(minBodyGroupId, maxBodyGroupId) {}
 
         INST_BODY
         INST_BODY_FREE(SetMixin)
@@ -1274,14 +1275,14 @@ namespace UnifiedRegex
 
     struct RepeatLoopIfCharInst : Inst, RepeatLoopMixin
     {
-        inline RepeatLoopIfCharInst(Label beginLabel) : Inst(RepeatLoopIfChar), RepeatLoopMixin(beginLabel) {}
+        inline RepeatLoopIfCharInst(Label beginLabel) : Inst(InstTag::RepeatLoopIfChar), RepeatLoopMixin(beginLabel) {}
 
         INST_BODY
     };
 
     struct RepeatLoopIfSetInst : Inst, RepeatLoopMixin
     {
-        inline RepeatLoopIfSetInst(Label beginLabel) : Inst(RepeatLoopIfSet), RepeatLoopMixin(beginLabel) {}
+        inline RepeatLoopIfSetInst(Label beginLabel) : Inst(InstTag::RepeatLoopIfSet), RepeatLoopMixin(beginLabel) {}
 
         INST_BODY
     };
@@ -1291,14 +1292,14 @@ namespace UnifiedRegex
     {
         // exitLabel must always be fixed up
         inline BeginLoopFixedInst(int loopId, const CountDomain& repeats, bool hasOuterLoops, CharCount length)
-            : Inst(BeginLoopFixed), BeginLoopMixin(loopId, repeats, hasOuterLoops, false), FixedLengthMixin(length) {}
+            : Inst(InstTag::BeginLoopFixed), BeginLoopMixin(loopId, repeats, hasOuterLoops, false), FixedLengthMixin(length) {}
 
         INST_BODY
     };
 
     struct RepeatLoopFixedInst : Inst, RepeatLoopMixin
     {
-        inline RepeatLoopFixedInst(Label beginLabel) : Inst(RepeatLoopFixed), RepeatLoopMixin(beginLabel) {}
+        inline RepeatLoopFixedInst(Label beginLabel) : Inst(InstTag::RepeatLoopFixed), RepeatLoopMixin(beginLabel) {}
 
         INST_BODY
     };
@@ -1308,7 +1309,7 @@ namespace UnifiedRegex
     {
         // set must always be cloned from source
         inline LoopSetInst(int loopId, const CountDomain& repeats, bool hasOuterLoops)
-            : Inst(LoopSet), BeginLoopBasicsMixin(loopId, repeats, hasOuterLoops) {}
+            : Inst(InstTag::LoopSet), BeginLoopBasicsMixin(loopId, repeats, hasOuterLoops) {}
 
         inline LoopSetInst(InstTag tag, int loopId, const CountDomain& repeats, bool hasOuterLoops)
             : Inst(tag), BeginLoopBasicsMixin(loopId, repeats, hasOuterLoops) {}
@@ -1331,14 +1332,14 @@ namespace UnifiedRegex
     {
         // exitLabel must always be fixed up
         inline BeginLoopFixedGroupLastIterationInst(int loopId, const CountDomain& repeats, bool hasOuterLoops, CharCount length, int groupId, bool noNeedToSave)
-            : Inst(BeginLoopFixedGroupLastIteration), BeginLoopMixin(loopId, repeats, hasOuterLoops, false), FixedLengthMixin(length), GroupMixin(groupId), NoNeedToSaveMixin(noNeedToSave) {}
+            : Inst(InstTag::BeginLoopFixedGroupLastIteration), BeginLoopMixin(loopId, repeats, hasOuterLoops, false), FixedLengthMixin(length), GroupMixin(groupId), NoNeedToSaveMixin(noNeedToSave) {}
 
         INST_BODY
     };
 
     struct RepeatLoopFixedGroupLastIterationInst : Inst, RepeatLoopMixin
     {
-        inline RepeatLoopFixedGroupLastIterationInst(Label beginLabel) : Inst(RepeatLoopFixedGroupLastIteration), RepeatLoopMixin(beginLabel) {}
+        inline RepeatLoopFixedGroupLastIterationInst(Label beginLabel) : Inst(InstTag::RepeatLoopFixedGroupLastIteration), RepeatLoopMixin(beginLabel) {}
 
         INST_BODY
     };
@@ -1347,14 +1348,14 @@ namespace UnifiedRegex
     struct BeginGreedyLoopNoBacktrackInst : Inst, GreedyLoopNoBacktrackMixin
     {
         // exitLabel must always be fixed up
-        inline BeginGreedyLoopNoBacktrackInst(int loopId) : Inst(BeginGreedyLoopNoBacktrack), GreedyLoopNoBacktrackMixin(loopId) {}
+        inline BeginGreedyLoopNoBacktrackInst(int loopId) : Inst(InstTag::BeginGreedyLoopNoBacktrack), GreedyLoopNoBacktrackMixin(loopId) {}
 
         INST_BODY
     };
 
     struct RepeatGreedyLoopNoBacktrackInst : Inst, RepeatLoopMixin
     {
-        inline RepeatGreedyLoopNoBacktrackInst(Label beginLabel) : Inst(RepeatGreedyLoopNoBacktrack), RepeatLoopMixin(beginLabel) {}
+        inline RepeatGreedyLoopNoBacktrackInst(Label beginLabel) : Inst(InstTag::RepeatGreedyLoopNoBacktrack), RepeatLoopMixin(beginLabel) {}
 
         INST_BODY
     };
@@ -1362,7 +1363,7 @@ namespace UnifiedRegex
     template<ChompMode Mode>
     struct ChompCharInst : Inst, CharMixin
     {
-        ChompCharInst(const Char c) : Inst(Mode == ChompMode::Star ? ChompCharStar : ChompCharPlus), CharMixin(c) {}
+        ChompCharInst(const Char c) : Inst(Mode == ChompMode::Star ? InstTag::ChompCharStar : InstTag::ChompCharPlus), CharMixin(c) {}
 
         INST_BODY
     };
@@ -1371,7 +1372,7 @@ namespace UnifiedRegex
     struct ChompSetInst : Inst, SetMixin<false>
     {
         // set must always be cloned from source
-        ChompSetInst() : Inst(Mode == ChompMode::Star ? ChompSetStar : ChompSetPlus) {}
+        ChompSetInst() : Inst(Mode == ChompMode::Star ? InstTag::ChompSetStar : InstTag::ChompSetPlus) {}
 
         INST_BODY
         INST_BODY_FREE(SetMixin)
@@ -1381,7 +1382,7 @@ namespace UnifiedRegex
     struct ChompCharGroupInst : Inst, CharMixin, GroupMixin, NoNeedToSaveMixin
     {
         ChompCharGroupInst(const Char c, const int groupId, const bool noNeedToSave)
-            : Inst(Mode == ChompMode::Star ? ChompCharGroupStar : ChompCharGroupPlus),
+            : Inst(Mode == ChompMode::Star ? InstTag::ChompCharGroupStar : InstTag::ChompCharGroupPlus),
             CharMixin(c),
             GroupMixin(groupId),
             NoNeedToSaveMixin(noNeedToSave)
@@ -1396,7 +1397,7 @@ namespace UnifiedRegex
     {
         // set must always be cloned from source
         ChompSetGroupInst(const int groupId, const bool noNeedToSave)
-            : Inst(Mode == ChompMode::Star ? ChompSetGroupStar : ChompSetGroupPlus),
+            : Inst(Mode == ChompMode::Star ? InstTag::ChompSetGroupStar : InstTag::ChompSetGroupPlus),
             GroupMixin(groupId),
             NoNeedToSaveMixin(noNeedToSave)
         {
@@ -1408,7 +1409,7 @@ namespace UnifiedRegex
 
     struct ChompCharBoundedInst : Inst, CharMixin, ChompBoundedMixin
     {
-        inline ChompCharBoundedInst(Char c, const CountDomain& repeats) : Inst(ChompCharBounded), CharMixin(c), ChompBoundedMixin(repeats) {}
+        inline ChompCharBoundedInst(Char c, const CountDomain& repeats) : Inst(InstTag::ChompCharBounded), CharMixin(c), ChompBoundedMixin(repeats) {}
 
         INST_BODY
     };
@@ -1416,7 +1417,7 @@ namespace UnifiedRegex
     struct ChompSetBoundedInst : Inst, SetMixin<false>, ChompBoundedMixin
     {
         // set must always be cloned from source
-        inline ChompSetBoundedInst(const CountDomain& repeats) : Inst(ChompSetBounded), ChompBoundedMixin(repeats) {}
+        inline ChompSetBoundedInst(const CountDomain& repeats) : Inst(InstTag::ChompSetBounded), ChompBoundedMixin(repeats) {}
 
         INST_BODY
         INST_BODY_FREE(SetMixin)
@@ -1425,7 +1426,7 @@ namespace UnifiedRegex
     struct ChompSetBoundedGroupLastCharInst : Inst, SetMixin<false>, ChompBoundedMixin, GroupMixin, NoNeedToSaveMixin
     {
         // set must always be cloned from source
-        inline ChompSetBoundedGroupLastCharInst(const CountDomain& repeats, int groupId, bool noNeedToSave) : Inst(ChompSetBoundedGroupLastChar), ChompBoundedMixin(repeats), GroupMixin(groupId), NoNeedToSaveMixin(noNeedToSave) {}
+        inline ChompSetBoundedGroupLastCharInst(const CountDomain& repeats, int groupId, bool noNeedToSave) : Inst(InstTag::ChompSetBoundedGroupLastChar), ChompBoundedMixin(repeats), GroupMixin(groupId), NoNeedToSaveMixin(noNeedToSave) {}
 
         INST_BODY
         INST_BODY_FREE(SetMixin)
@@ -1438,7 +1439,7 @@ namespace UnifiedRegex
     struct TryInst : Inst, TryMixin
     {
         // failLabel must always be fixed up
-        inline TryInst() : Inst(Try), TryMixin() {}
+        inline TryInst() : Inst(InstTag::Try), TryMixin() {}
 
         INST_BODY
     };
@@ -1446,7 +1447,7 @@ namespace UnifiedRegex
     struct TryIfCharInst : Inst, CharMixin, TryMixin
     {
         // failLabel must always be fixed up
-        inline TryIfCharInst(Char c) : Inst(TryIfChar), CharMixin(c), TryMixin() {}
+        inline TryIfCharInst(Char c) : Inst(InstTag::TryIfChar), CharMixin(c), TryMixin() {}
 
         INST_BODY
     };
@@ -1454,7 +1455,7 @@ namespace UnifiedRegex
     struct TryMatchCharInst : Inst, CharMixin, TryMixin
     {
         // failLabel must always be fixed up
-        inline TryMatchCharInst(Char c) : Inst(TryMatchChar), CharMixin(c), TryMixin() {}
+        inline TryMatchCharInst(Char c) : Inst(InstTag::TryMatchChar), CharMixin(c), TryMixin() {}
 
         INST_BODY
     };
@@ -1463,7 +1464,7 @@ namespace UnifiedRegex
     {
         // set is always same as matching BeginLoopIfSetInst set
         // failLabel must always be fixed up
-        inline TryIfSetInst() : Inst(TryIfSet), TryMixin() {}
+        inline TryIfSetInst() : Inst(InstTag::TryIfSet), TryMixin() {}
 
         INST_BODY
         INST_BODY_FREE(SetMixin)
@@ -1473,7 +1474,7 @@ namespace UnifiedRegex
     {
         // set is always same as matching BeginLoopIfSetInst set
         // failLabel must always be fixed up
-        inline TryMatchSetInst() : Inst(TryMatchSet), TryMixin() {}
+        inline TryMatchSetInst() : Inst(InstTag::TryMatchSet), TryMixin() {}
 
         INST_BODY
         INST_BODY_FREE(SetMixin)
@@ -1487,7 +1488,7 @@ namespace UnifiedRegex
     {
         // nextLabel must always be fixed up
         inline BeginAssertionInst(bool isNegation, int minBodyGroupId, int maxBodyGroupId)
-            : Inst(BeginAssertion), BodyGroupsMixin(minBodyGroupId, maxBodyGroupId), NegationMixin(isNegation), NextLabelMixin()
+            : Inst(InstTag::BeginAssertion), BodyGroupsMixin(minBodyGroupId, maxBodyGroupId), NegationMixin(isNegation), NextLabelMixin()
         {}
 
         INST_BODY
@@ -1495,7 +1496,7 @@ namespace UnifiedRegex
 
     struct EndAssertionInst : Inst
     {
-        inline EndAssertionInst() : Inst(EndAssertion) {}
+        inline EndAssertionInst() : Inst(InstTag::EndAssertion) {}
 
         INST_BODY
     };
@@ -1575,7 +1576,7 @@ namespace UnifiedRegex
 
     struct Cont : protected Chars<char16>
     {
-        enum ContTag : uint32
+        enum class ContTag : uint8
         {
 #define M(O) O,
 #include "RegexContcodes.h"
@@ -1606,7 +1607,7 @@ namespace UnifiedRegex
         CharCount origInputOffset;
         Label origInstLabel;
 
-        inline ResumeCont(CharCount origInputOffset, Label origInstLabel) : Cont(Resume), origInputOffset(origInputOffset), origInstLabel(origInstLabel) {}
+        inline ResumeCont(CharCount origInputOffset, Label origInstLabel) : Cont(ContTag::Resume), origInputOffset(origInputOffset), origInstLabel(origInstLabel) {}
 
         CONT_BODY
     };
@@ -1627,7 +1628,7 @@ namespace UnifiedRegex
         GroupInfo origGroupInfo;
 
         RestoreGroupCont(int groupId, const GroupInfo &origGroupInfo)
-            : Cont(RestoreGroup), groupId(groupId), origGroupInfo(origGroupInfo)
+            : Cont(ContTag::RestoreGroup), groupId(groupId), origGroupInfo(origGroupInfo)
         {
         }
 
@@ -1638,7 +1639,7 @@ namespace UnifiedRegex
     {
         const int groupId;
 
-        ResetGroupCont(const int groupId) : Cont(ResetGroup), groupId(groupId) {}
+        ResetGroupCont(const int groupId) : Cont(ContTag::ResetGroup), groupId(groupId) {}
 
         CONT_BODY
     };
@@ -1649,7 +1650,7 @@ namespace UnifiedRegex
         const int toGroupId;
 
         ResetGroupRangeCont(const int fromGroupId, const int toGroupId)
-            : Cont(ResetGroupRange), fromGroupId(fromGroupId), toGroupId(toGroupId)
+            : Cont(ContTag::ResetGroupRange), fromGroupId(fromGroupId), toGroupId(toGroupId)
         {
             Assert(fromGroupId >= 0);
             Assert(toGroupId >= 0);
@@ -1664,14 +1665,14 @@ namespace UnifiedRegex
         Label beginLabel;           // label of BeginLoop instruction
         CharCount origInputOffset;  // where to go back to
 
-        inline RepeatLoopCont(Label beginLabel, CharCount origInputOffset) : Cont(RepeatLoop), beginLabel(beginLabel), origInputOffset(origInputOffset) {}
+        inline RepeatLoopCont(Label beginLabel, CharCount origInputOffset) : Cont(ContTag::RepeatLoop), beginLabel(beginLabel), origInputOffset(origInputOffset) {}
 
         CONT_BODY
     };
 
     struct PopAssertionCont : Cont
     {
-        inline PopAssertionCont() : Cont(PopAssertion) {}
+        inline PopAssertionCont() : Cont(ContTag::PopAssertion) {}
 
         CONT_BODY
     };
@@ -1681,7 +1682,7 @@ namespace UnifiedRegex
         Label beginLabel;   // label of BeginLoopFixed instruction
         bool tryingBody;    // true if attempting an additional iteration of loop body, otherwise attempting loop follow
 
-        inline RewindLoopFixedCont(Label beginLabel, bool tryingBody) : Cont(RewindLoopFixed), beginLabel(beginLabel), tryingBody(tryingBody) {}
+        inline RewindLoopFixedCont(Label beginLabel, bool tryingBody) : Cont(ContTag::RewindLoopFixed), beginLabel(beginLabel), tryingBody(tryingBody) {}
 
         CONT_BODY
     };
@@ -1690,7 +1691,7 @@ namespace UnifiedRegex
     {
         Label beginLabel;   // label of LoopSet instruction
 
-        inline RewindLoopSetCont(Label beginLabel) : Cont(RewindLoopSet), beginLabel(beginLabel) {}
+        inline RewindLoopSetCont(Label beginLabel) : Cont(ContTag::RewindLoopSet), beginLabel(beginLabel) {}
 
         CONT_BODY
     };
@@ -1699,7 +1700,7 @@ namespace UnifiedRegex
     {
         Label beginLabel;   // label of LoopSet instruction
 
-        inline RewindLoopSetWithFollowFirstCont(Label beginLabel) : Cont(RewindLoopSetWithFollowFirst), beginLabel(beginLabel) {}
+        inline RewindLoopSetWithFollowFirstCont(Label beginLabel) : Cont(ContTag::RewindLoopSetWithFollowFirst), beginLabel(beginLabel) {}
 
         CONT_BODY
     };
@@ -1709,7 +1710,7 @@ namespace UnifiedRegex
         Label beginLabel;   // label of BeginLoopFixedGroupLastIteration instruction
         bool tryingBody;    // true if attempting an additional iteration of loop body, otherwise attempting loop follow
 
-        inline RewindLoopFixedGroupLastIterationCont(Label beginLabel, bool tryingBody) : Cont(RewindLoopFixedGroupLastIteration), beginLabel(beginLabel), tryingBody(tryingBody) {}
+        inline RewindLoopFixedGroupLastIterationCont(Label beginLabel, bool tryingBody) : Cont(ContTag::RewindLoopFixedGroupLastIteration), beginLabel(beginLabel), tryingBody(tryingBody) {}
 
         CONT_BODY
     };
@@ -1755,7 +1756,7 @@ namespace UnifiedRegex
         AssertionStack assertionStack;
     };
 
-    enum HardFailMode
+    enum class HardFailMode
     {
         BacktrackAndLater,
         BacktrackOnly,