Ejemplo n.º 1
0
        private static Update UpdateState(IList <Instruction> instructions, State state, PushedArgs pushedArgs)
        {
            if (state.index < 0 || state.index >= instructions.Count)
            {
                return(Update.Fail);
            }
            var instr = instructions[state.index];

            if (!Instr.IsFallThrough(instr.OpCode))
            {
                return(Update.Fail);
            }
            instr.CalculateStackUsage(false, out int pushes, out int pops);
            if (pops == -1)
            {
                return(Update.Fail);
            }
            var isDup = instr.OpCode.Code == Code.Dup;

            if (isDup)
            {
                pushes = 1;
                pops   = 0;
            }
            if (pushes > 1)
            {
                return(Update.Fail);
            }

            if (state.skipPushes > 0)
            {
                state.skipPushes -= pushes;
                if (state.skipPushes < 0)
                {
                    return(Update.Fail);
                }
                state.skipPushes += pops;
            }
            else
            {
                if (pushes == 1)
                {
                    if (isDup)
                    {
                        state.addPushes++;
                    }
                    else
                    {
                        for (; state.addPushes > 0; state.addPushes--)
                        {
                            pushedArgs.Add(instr);
                            state.validArgs++;
                            if (!pushedArgs.CanAddMore)
                            {
                                return(Update.Finish);
                            }
                        }
                        state.addPushes = 1;
                    }
                }
                state.skipPushes += pops;
            }
            return(Update.Ok);
        }