Пример #1
0
 public IActionCode LdMatcherBuffer()
 {
     emit
     .Do(ldCursor)
     .Ldfld((ScanCursor c) => c.Buffer);
     return(this);
 }
        public EmitSyntax Build(EmitSyntax emit)
        {
            int rows    = table.RowCount;
            int columns = table.ColumnCount;

            Ref <Labels> END = emit.Labels.Generate().GetRef();

            Ref <Labels>[] labels = new Ref <Labels> [rows];
            for (int i = 0; i != rows; ++i)
            {
                labels[i] = emit.Labels.Generate().GetRef();
            }

            emit
            .Do(LdRow)
            .Switch(labels)
            .Ldc_I4(-1)
            .Br(END)
            ;

            var columnRange     = new IntInterval(0, columns - 1);
            var columnFrequency = new UniformIntFrequency(columnRange);

            for (int i = 0; i != rows; ++i)
            {
                var switchEmitter = SwitchGenerator.Sparse(table.GetRow(i), columnRange, columnFrequency);

                emit.Label(labels[i].Def);
                switchEmitter.Build(emit, LdCol, SwitchGenerator.LdValueAction(END));
            }

            return(emit.Label(END.Def));
        }
Пример #3
0
        private IActionCode LdActionArgument(int index)
        {
            emit = emit
                   .Do(LdRuleArgs)
                   .Do(LdArgsStart);

            // Optmization for "+ 0".
            if (index != 0)
            {
                emit
                .Ldc_I4(index)
                .Add();
            }

            if (typeof(Msg).IsValueType)
            {
                emit = emit
                       .Ldelema(emit.Types.Import(typeof(Msg)));
            }
            else
            {
                emit = emit
                       .Ldelem_Ref();
            }

            emit = emit
                   .Ldfld((Msg msg) => msg.Value)
            ;

            return(this);
        }
        public EmitSyntax Build(EmitSyntax emit)
        {
            int rows = table.RowCount;
            int columns = table.ColumnCount;

            Ref<Labels> END = emit.Labels.Generate().GetRef();
            Ref<Labels>[] labels = new Ref<Labels>[rows];
            for (int i = 0; i != rows; ++i)
            {
                labels[i] = emit.Labels.Generate().GetRef();
            }

            emit
                .Do(LdRow)
                .Switch(labels)
                .Ldc_I4(-1)
                .Br(END)
                ;

            var columnRange = new IntInterval(0, columns - 1);
            var columnFrequency = new UniformIntFrequency(columnRange);
            for (int i = 0; i != rows; ++i)
            {
                var switchEmitter = SwitchGenerator.Sparse(table.GetRow(i), columnRange, columnFrequency);

                emit.Label(labels[i].Def);
                switchEmitter.Build(emit, LdCol, SwitchGenerator.LdValueAction(END));
            }

            return emit .Label(END.Def);
        }
        protected override void DoBuild(EmitSyntax emit, Pipe<EmitSyntax> ldvalue, SwitchGeneratorAction action)
        {
            var labels = new Ref<Labels>[map.Length];
            for (int i = 0; i != labels.Length; ++i)
            {
                labels[i] = emit.Labels.Generate().GetRef();
            }

            emit
                .Do(ldvalue)
                .Switch(labels)
                ;

            action(emit, defaultValue);

            for (int i = 0; i != labels.Length; ++i)
            {
                emit.Label(labels[i].Def);
                action(emit, map[i]);
            }
        }
        protected override void DoBuild(EmitSyntax emit, Pipe <EmitSyntax> ldvalue, SwitchGeneratorAction action)
        {
            var labels = new Ref <Labels> [map.Length];

            for (int i = 0; i != labels.Length; ++i)
            {
                labels[i] = emit.Labels.Generate().GetRef();
            }

            emit
            .Do(ldvalue)
            .Switch(labels)
            ;

            action(emit, defaultValue);

            for (int i = 0; i != labels.Length; ++i)
            {
                emit.Label(labels[i].Def);
                action(emit, map[i]);
            }
        }
Пример #7
0
        public ILNfaCompiler(AstNode node, EmitSyntax emit, ILCompilerSettings settings)
        {
            this.Scanner = new StemScanner();

            this.emit = emit;
            this.settings = settings;

            var labels = emit.Labels;
            NEXT_THREAD     = labels.Generate();
            RESUME_ALL      = labels.Generate();
            NEXT_INPUT      = labels.Generate();
            THREAD_SUSPEND  = labels.Generate();
            THREAD_DISPATCH = labels.Generate();

            var LABEL0      = labels.Generate();
            var LABEL1      = labels.Generate();
            var POSTCOMPILEINIT = labels.Generate();
            var POSTCOMPILEINIT_BACK = labels.Generate();

            var locals = emit.Locals;
            slots        = locals.Generate();
            labelIndexToLocation = locals.Generate();
            intTmp       = locals.Generate();
            threadTmp    = locals.Generate();

            INfaVM code = this;

            this.inputPump = new ArrayLoopGenerator(
                       valueType: emit.Types.Int32,
                       ldarray:   settings.LdInput,
                       body:
                           il => il
                               .Do(matchedStack.Clear)
                               .Br(RESUME_ALL.GetRef())
                        );

            this.runningStack   = new StackGenerator(emit, typeof(Thread));
            this.suspendedStack = new StackGenerator(emit, typeof(Thread));
            this.matchedStack   = new StackGenerator(emit, typeof(Thread));
            this.tmpStack       = new StackGenerator(emit, typeof(Thread), nullContainer: true);

            emit
                .Local(intTmp, emit.Types.Int32)
                .Local(slots, emit.Types.Import(typeof(int[])))
                .Local(labelIndexToLocation, emit.Types.Import(typeof(int[])))
                .Br(POSTCOMPILEINIT.GetRef())
                .Label(POSTCOMPILEINIT_BACK)
                .Local(threadTmp, emit.Types.Import(typeof(Thread)))
                .Ldloca(threadTmp.GetRef())
                .Initobj(emit.Types.Import(typeof(Thread)))
                .Do(inputPump.EmitInitialization)
                ;

            new RegularNfaVMCompiler().Compile(node, code);

            int LabelCount = Math.Max(1, indexToLabel.Count);

            this.runningStack.SetSize(LabelCount);
            this.suspendedStack.SetSize(LabelCount);
            this.matchedStack.SetSize(LabelCount);
            this.tmpStack.SetSize(LabelCount);

            emit
                .Label(POSTCOMPILEINIT)
                .Do(runningStack.Init)
                .Do(suspendedStack.Init)
                .Do(matchedStack.Init)
                .Do(tmpStack.Init)
                .Ldc_I4(slotCount)
                .Newarr(emit.Types.Int32)
                .Stloc(slots.GetRef())

                .Ldc_I4(LabelCount)
                .Newarr(emit.Types.Int32)
                .Stloc(labelIndexToLocation.GetRef())
                // Fill labelIndexToLocation with -1 :
                .Ldc_I4(LabelCount).Stloc(intTmp.GetRef())

                .Label(LABEL1)
                .Ldloc(intTmp.GetRef())
                .Ldc_I4_0()
                .Beq(LABEL0.GetRef())
                .Ldloc(intTmp.GetRef())
                .Ldc_I4(1)
                .Sub()
                .Stloc(intTmp.GetRef())
                .Ldloc(labelIndexToLocation.GetRef())
                .Ldloc(intTmp.GetRef())
                .Ldc_I4(int.MinValue)
                .Stelem_I4()
                .Br(LABEL1.GetRef())
                .Label(LABEL0)
                .Br(POSTCOMPILEINIT_BACK.GetRef());

            // Save thread as suspended (stack should already contain label index to suspend)
            emit.Label(THREAD_SUSPEND);
            StThreadValueByRuntimeLabelIndex();
            emit
                // Don't add thread if same thread (same label index
                // with current input location) already exists in a list.
                .Ldloc(labelIndexToLocation.GetRef())
                .Ldloca(threadTmp.GetRef())
                .Ldfld(LabelIndexField)
                .Ldelem_I4()
                .Ldloc(inputPump.Index.GetRef())
                .Beq(NEXT_THREAD.GetRef())

                // Mark label index as visited
                .Ldloc(labelIndexToLocation.GetRef())
                .Ldloca(threadTmp.GetRef())
                .Ldfld(LabelIndexField)
                .Ldloc(inputPump.Index.GetRef())
                .Stelem_I4()
                ;

            suspendedStack.PushFrom(emit, threadTmp);

            emit
                .Br(NEXT_THREAD.GetRef())

                .Label(RESUME_ALL)
                .Swap(suspendedStack.Stack, runningStack.Stack, tmpStack.Stack)
                .Swap(suspendedStack.Index, runningStack.Index, tmpStack.Index)
                .Label(NEXT_THREAD)
                ;

            runningStack
                .StackLoop(
                    emit,
                    (emit2, thread) =>
                    {
                        emit2
                            .Ldloca(thread.GetRef())
                            .Ldfld(LabelIndexField)
                            .Label(THREAD_DISPATCH)
                            .Switch(indexToLabel.Select(def => def.GetRef()).ToArray())
                            .Br(settings.FAILURE.GetRef());
                    })
                    ;
            emit
                .Br(NEXT_INPUT.GetRef())
                ;

            emit
                .Label(NEXT_INPUT)
                ;

            inputPump.EmitLoopPass(emit, false);

            emit
                // Check if there are matched threads:
                .Do(matchedStack.LdCount)
                .Ldc_I4_0()
                .Beq(settings.FAILURE.GetRef())
                .Br(settings.SUCCESS.GetRef());
        }
        public void Build(
            EmitSyntax emit,
            Pipe <EmitSyntax> ldCursor,
            Pipe <EmitSyntax> ldTokenPtr)
        {
            var labels = emit.Labels;
            var locals = emit.Locals;

            var RETURN = labels.Generate();

            var valueTmp = locals.Generate();
            var tokenId  = locals.Generate();

            emit
            .Local(valueTmp, emit.Types.Object)
            .Ldnull()
            .Stloc(valueTmp.GetRef())

            .Local(tokenId, emit.Types.Int32)
            .Ldc_I4(-1)
            .Stloc(tokenId.GetRef())
            ;

            int ruleCount = data.Grammar.Conditions.Sum(cond => cond.Matchers.Count);

            var action = new Ref <Labels> [ruleCount];

            for (int i = 0; i != ruleCount; ++i)
            {
                action[i] = labels.Generate().GetRef();
            }

            emit
            .Do(ldCursor)
            .Ldfld((ScanCursor c) => c.CurrentActionId)
            .Switch(action)
            ;

            foreach (var cond in data.Grammar.Conditions)
            {
                var contextResolver = new ContextCode(
                    emit,
                    il => il
                    .Do(ldCursor)
                    .Ldfld((ScanCursor c) => c.RootContext),
                    null,
                    data,
                    cond.ContextProvider);
                IActionCode code = new MatcherCode(
                    emit,
                    contextResolver,
                    ldCursor,
                    declaringType,
                    data.Grammar.Conditions,
                    RETURN.GetRef());

                foreach (var matcher in cond.Matchers)
                {
                    emit
                    .Label(action[matcher.Index].Def)
                    .Ldc_I4(matcher.Outcome == null ? -1 : matcher.Outcome.Index)
                    .Stloc(tokenId.GetRef())
                    ;

                    var productionBinding = matcher.Joint.The <CilMatcher>();
                    code = code
                           .Do(productionBinding.Context.Load)
                           .Do(productionBinding.ActionBuilder);
                }
            }

            // Load null value for incorrectly implemented actions
            emit.Ldnull();

            emit
            .Label(RETURN)

            .Stloc(valueTmp.GetRef())
            .Do(ldTokenPtr)
            .Ldloc(valueTmp.GetRef())
            .Stind_Ref()

            .Ldloc(tokenId.GetRef())
            .Ret()
            ;
        }
Пример #9
0
        public void BuildBody(
            EmitSyntax emit,
            LanguageData data,
            Ref <Args> ruleId,
            Ref <Args> ruleArgs,
            Ref <Args> argsStart,
            Ref <Args> ctx,
            Ref <Args> lookbackStart)
        {
            Def <Labels> returnLabel = emit.Labels.Generate();

            var contextCode = new ContextCode(
                emit,
                il => il.Ldarg(ctx),
                il => il.Ldarg(lookbackStart),
                data,
                data.Grammar.GlobalContextProvider,
                data.LocalParseContexts);

            IActionCode code = new ProductionCode(
                emit,
                contextCode,
                ldRuleArgs:  il => il.Ldarg(ruleArgs),
                ldArgsStart: il => il.Ldarg(argsStart),
                returnLabel: returnLabel);

            var defaultLabel             = emit.Labels.Generate();
            var endWithSingleResultLabel = emit.Labels.Generate();
            var jumpTable = new Ref <Labels> [data.Grammar.Productions.Count];

            for (int i = 0; i != jumpTable.Length; ++i)
            {
                jumpTable[i] = emit.Labels.Generate().GetRef();
            }

            emit
            .Do(il => il.Ldarg(ruleId))
            .Switch(jumpTable)
            .Br(defaultLabel.GetRef());

            foreach (var prod in data.Grammar.Productions)
            {
                emit.Label(jumpTable[prod.Index].Def);

                if (0 == prod.Actions.Count)
                {
                    // Augumented start rule has null action and should never be invoked.
                    // Also it is possible that for some platforms production may have default
                    // action.
                    emit.Ldnull();
                }
                else
                {
                    foreach (var action in prod.Actions)
                    {
                        code = GenerateActionCode(code, action);
                    }
                }

                emit.Br(endWithSingleResultLabel.GetRef());
            }

            emit
            .Label(defaultLabel)
            .Ldnull()
            .Label(endWithSingleResultLabel)
            .Label(returnLabel)
            .Ret();
        }
Пример #10
0
 public IActionCode Emit(Pipe <EmitSyntax> pipe)
 {
     emit = emit.Do(pipe);
     return(this);
 }
        public EmitSyntax Build(EmitSyntax emit)
        {
            int rows = table.RowCount;
            int columns = table.ColumnCount;

            // Dispatch info index
            Ref<Labels> DISP_INFO = emit.Labels.Generate().GetRef();
            // Return no-data result
            Ref<Labels> RET_NONE = emit.Labels.Generate().GetRef();
            // Exit
            Ref<Labels> END = emit.Labels.Generate().GetRef();
            Ref<Labels>[] rowLabels = new Ref<Labels>[rows];
            for (int i = 0; i != rows; ++i)
            {
                rowLabels[i] = emit.Labels.Generate().GetRef();
            }

            emit
                .Do(LdRow)
                .Switch(rowLabels)
                .Br(RET_NONE)
                ;

            for (int i = 0; i != rows; ++i)
            {
                emit
                    .Label(rowLabels[i].Def)
                    .Ldc_I4(table.RowToOffset[i])
                    .Br(DISP_INFO);
            }

            int infoCount = table.Info.Count;
            var infoLabels = new Ref<Labels>[infoCount];
            for (int i = 0; i != infoCount; ++i)
            {
                infoLabels[i] = emit.Labels.Generate().GetRef();
            }

            emit
                .Label(DISP_INFO.Def)
                // Row offset should already be in stack
                .Do(LdCol)
                .Add()
                .Switch(infoLabels)
                .Br(RET_NONE);
            for (int i = 0; i != infoCount; ++i)
            {
                emit
                    .Label(infoLabels[i].Def)
                    .Do(LdRow)
                    .Ldc_I4(table.Check[i])
                    .Bne_Un(RET_NONE)
                    .Ldc_I4(table.Info[i])
                    .Br(END)
                    ;
            }

            emit
                .Label(RET_NONE.Def)
                .Ldc_I4(0)
                ;
            return emit.Label(END.Def);
        }
        public void BuildBody(
            EmitSyntax emit, 
            LanguageData data,
            Ref<Args> ruleId,
            Ref<Args> ruleArgs,
            Ref<Args> argsStart,
            Ref<Args> ctx,
            Ref<Args> lookbackStart)
        {
            Def<Labels> returnLabel = emit.Labels.Generate();

            var contextCode = new ContextCode(
                emit,
                il => il.Ldarg(ctx),
                il => il.Ldarg(lookbackStart),
                data,
                data.Grammar.GlobalContextProvider,
                data.LocalParseContexts);

            IActionCode code = new ProductionCode(
                emit,
                contextCode,
                ldRuleArgs:  il => il.Ldarg(ruleArgs),
                ldArgsStart: il => il.Ldarg(argsStart),
                returnLabel: returnLabel);

            var defaultLabel = emit.Labels.Generate();
            var endWithSingleResultLabel = emit.Labels.Generate();
            var jumpTable = new Ref<Labels>[data.Grammar.Productions.Count];
            for (int i = 0; i != jumpTable.Length; ++i)
            {
                jumpTable[i] = emit.Labels.Generate().GetRef();
            }

            emit
                .Do(il => il.Ldarg(ruleId))
                .Switch(jumpTable)
                .Br(defaultLabel.GetRef());

            foreach (var prod in data.Grammar.Productions)
            {
                emit.Label(jumpTable[prod.Index].Def);

                if (0 == prod.Actions.Count)
                {
                    // Augumented start rule has null action and should never be invoked.
                    // Also it is possible that for some platforms production may have default
                    // action.
                    emit.Ldnull();
                }
                else
                {
                    foreach (var action in prod.Actions)
                    {
                        code = GenerateActionCode(code, action);
                    }
                }

                emit.Br(endWithSingleResultLabel.GetRef());
            }

            emit
                .Label(defaultLabel)
                .Ldnull()
                .Label(endWithSingleResultLabel)
                .Label(returnLabel)
                .Ret();
        }
        public void Build(
            EmitSyntax          emit,
            Pipe<EmitSyntax>    ldCursor,
            Pipe<EmitSyntax>    ldTokenPtr)
        {
            var labels = emit.Labels;
            var locals = emit.Locals;

            var RETURN = labels.Generate();

            var valueTmp = locals.Generate();
            var tokenId  = locals.Generate();

            emit
                .Local(valueTmp, emit.Types.Object)
                .Ldnull()
                .Stloc(valueTmp.GetRef())

                .Local(tokenId, emit.Types.Int32)
                .Ldc_I4(-1)
                .Stloc(tokenId.GetRef())
                ;

            int ruleCount = data.Grammar.Conditions.Sum(cond => cond.Matchers.Count);

            var action = new Ref<Labels>[ruleCount];
            for (int i = 0; i != ruleCount; ++i)
            {
                action[i] = labels.Generate().GetRef();
            }

            emit
                .Do(ldCursor)
                .Ldfld((ScanCursor c) => c.CurrentActionId)
                .Switch(action)
                ;

            foreach (var cond in data.Grammar.Conditions)
            {
                var contextResolver = new ContextCode(
                                        emit,
                                        il => il
                                            .Do(ldCursor)
                                            .Ldfld((ScanCursor c) => c.RootContext),
                                        null,
                                        data,
                                        cond.ContextProvider);
                IActionCode code = new MatcherCode(
                                emit,
                                contextResolver,
                                ldCursor,
                                declaringType,
                                data.Grammar.Conditions,
                                RETURN.GetRef());

                foreach (var matcher in cond.Matchers)
                {
                    emit
                        .Label(action[matcher.Index].Def)
                        .Ldc_I4(matcher.Outcome == null ? -1 : matcher.Outcome.Index)
                        .Stloc(tokenId.GetRef())
                        ;

                    var productionBinding = matcher.Joint.The<CilMatcher>();
                    code = code
                        .Do(productionBinding.Context.Load)
                        .Do(productionBinding.ActionBuilder);
                }
            }

            // Load null value for incorrectly implemented actions
            emit.Ldnull();

            emit
                .Label(RETURN)

                .Stloc(valueTmp.GetRef())
                .Do(ldTokenPtr)
                .Ldloc(valueTmp.GetRef())
                .Stind_Ref()

                .Ldloc(tokenId.GetRef())
                .Ret()
                ;
        }
Пример #14
0
        public ILNfaCompiler(AstNode node, EmitSyntax emit, ILCompilerSettings settings)
        {
            this.Scanner = new StemScanner();

            this.emit     = emit;
            this.settings = settings;

            var labels = emit.Labels;

            NEXT_THREAD     = labels.Generate();
            RESUME_ALL      = labels.Generate();
            NEXT_INPUT      = labels.Generate();
            THREAD_SUSPEND  = labels.Generate();
            THREAD_DISPATCH = labels.Generate();

            var LABEL0               = labels.Generate();
            var LABEL1               = labels.Generate();
            var POSTCOMPILEINIT      = labels.Generate();
            var POSTCOMPILEINIT_BACK = labels.Generate();

            var locals = emit.Locals;

            slots = locals.Generate();
            labelIndexToLocation = locals.Generate();
            intTmp    = locals.Generate();
            threadTmp = locals.Generate();


            INfaVM code = this;

            this.inputPump = new ArrayLoopGenerator(
                valueType: emit.Types.Int32,
                ldarray:   settings.LdInput,
                body:
                il => il
                .Do(matchedStack.Clear)
                .Br(RESUME_ALL.GetRef())
                );

            this.runningStack   = new StackGenerator(emit, typeof(Thread));
            this.suspendedStack = new StackGenerator(emit, typeof(Thread));
            this.matchedStack   = new StackGenerator(emit, typeof(Thread));
            this.tmpStack       = new StackGenerator(emit, typeof(Thread), nullContainer: true);

            emit
            .Local(intTmp, emit.Types.Int32)
            .Local(slots, emit.Types.Import(typeof(int[])))
            .Local(labelIndexToLocation, emit.Types.Import(typeof(int[])))
            .Br(POSTCOMPILEINIT.GetRef())
            .Label(POSTCOMPILEINIT_BACK)
            .Local(threadTmp, emit.Types.Import(typeof(Thread)))
            .Ldloca(threadTmp.GetRef())
            .Initobj(emit.Types.Import(typeof(Thread)))
            .Do(inputPump.EmitInitialization)
            ;

            new RegularNfaVMCompiler().Compile(node, code);

            int LabelCount = Math.Max(1, indexToLabel.Count);

            this.runningStack.SetSize(LabelCount);
            this.suspendedStack.SetSize(LabelCount);
            this.matchedStack.SetSize(LabelCount);
            this.tmpStack.SetSize(LabelCount);

            emit
            .Label(POSTCOMPILEINIT)
            .Do(runningStack.Init)
            .Do(suspendedStack.Init)
            .Do(matchedStack.Init)
            .Do(tmpStack.Init)
            .Ldc_I4(slotCount)
            .Newarr(emit.Types.Int32)
            .Stloc(slots.GetRef())

            .Ldc_I4(LabelCount)
            .Newarr(emit.Types.Int32)
            .Stloc(labelIndexToLocation.GetRef())
            // Fill labelIndexToLocation with -1 :
            .Ldc_I4(LabelCount).Stloc(intTmp.GetRef())

            .Label(LABEL1)
            .Ldloc(intTmp.GetRef())
            .Ldc_I4_0()
            .Beq(LABEL0.GetRef())
            .Ldloc(intTmp.GetRef())
            .Ldc_I4(1)
            .Sub()
            .Stloc(intTmp.GetRef())
            .Ldloc(labelIndexToLocation.GetRef())
            .Ldloc(intTmp.GetRef())
            .Ldc_I4(int.MinValue)
            .Stelem_I4()
            .Br(LABEL1.GetRef())
            .Label(LABEL0)
            .Br(POSTCOMPILEINIT_BACK.GetRef());

            // Save thread as suspended (stack should already contain label index to suspend)
            emit.Label(THREAD_SUSPEND);
            StThreadValueByRuntimeLabelIndex();
            emit
            // Don't add thread if same thread (same label index
            // with current input location) already exists in a list.
            .Ldloc(labelIndexToLocation.GetRef())
            .Ldloca(threadTmp.GetRef())
            .Ldfld(LabelIndexField)
            .Ldelem_I4()
            .Ldloc(inputPump.Index.GetRef())
            .Beq(NEXT_THREAD.GetRef())

            // Mark label index as visited
            .Ldloc(labelIndexToLocation.GetRef())
            .Ldloca(threadTmp.GetRef())
            .Ldfld(LabelIndexField)
            .Ldloc(inputPump.Index.GetRef())
            .Stelem_I4()
            ;

            suspendedStack.PushFrom(emit, threadTmp);

            emit
            .Br(NEXT_THREAD.GetRef())

            .Label(RESUME_ALL)
            .Swap(suspendedStack.Stack, runningStack.Stack, tmpStack.Stack)
            .Swap(suspendedStack.Index, runningStack.Index, tmpStack.Index)
            .Label(NEXT_THREAD)
            ;

            runningStack
            .StackLoop(
                emit,
                (emit2, thread) =>
            {
                emit2
                .Ldloca(thread.GetRef())
                .Ldfld(LabelIndexField)
                .Label(THREAD_DISPATCH)
                .Switch(indexToLabel.Select(def => def.GetRef()).ToArray())
                .Br(settings.FAILURE.GetRef());
            })
            ;
            emit
            .Br(NEXT_INPUT.GetRef())
            ;

            emit
            .Label(NEXT_INPUT)
            ;

            inputPump.EmitLoopPass(emit, false);

            emit
            // Check if there are matched threads:
            .Do(matchedStack.LdCount)
            .Ldc_I4_0()
            .Beq(settings.FAILURE.GetRef())
            .Br(settings.SUCCESS.GetRef());
        }
Пример #15
0
        public EmitSyntax Build(EmitSyntax emit)
        {
            int rows    = table.RowCount;
            int columns = table.ColumnCount;

            // Dispatch info index
            Ref <Labels> DISP_INFO = emit.Labels.Generate().GetRef();
            // Return no-data result
            Ref <Labels> RET_NONE = emit.Labels.Generate().GetRef();
            // Exit
            Ref <Labels> END = emit.Labels.Generate().GetRef();

            Ref <Labels>[] rowLabels = new Ref <Labels> [rows];
            for (int i = 0; i != rows; ++i)
            {
                rowLabels[i] = emit.Labels.Generate().GetRef();
            }

            emit
            .Do(LdRow)
            .Switch(rowLabels)
            .Br(RET_NONE)
            ;

            for (int i = 0; i != rows; ++i)
            {
                emit
                .Label(rowLabels[i].Def)
                .Ldc_I4(table.RowToOffset[i])
                .Br(DISP_INFO);
            }

            int infoCount  = table.Info.Count;
            var infoLabels = new Ref <Labels> [infoCount];

            for (int i = 0; i != infoCount; ++i)
            {
                infoLabels[i] = emit.Labels.Generate().GetRef();
            }

            emit
            .Label(DISP_INFO.Def)
            // Row offset should already be in stack
            .Do(LdCol)
            .Add()
            .Switch(infoLabels)
            .Br(RET_NONE);
            for (int i = 0; i != infoCount; ++i)
            {
                emit
                .Label(infoLabels[i].Def)
                .Do(LdRow)
                .Ldc_I4(table.Check[i])
                .Bne_Un(RET_NONE)
                .Ldc_I4(table.Info[i])
                .Br(END)
                ;
            }

            emit
            .Label(RET_NONE.Def)
            .Ldc_I4(0)
            ;
            return(emit.Label(END.Def));
        }