Пример #1
0
        static public bool Detect(CodeBlock block, out StatementStructure statementStructure)
        {
            List <OpCode> brs = new List <OpCode> {
                OpCodes.Br_S, OpCodes.Br
            };

            statementStructure = null;

            if (!ConditionalBranch_OpCodes.Contains(block.first.OpCode))
            {
                return(false);
            }

            var conditionStatementBlock = Detect(block.first, block.last);

            if (conditionStatementBlock == null)
            {
                return(false);
            }
            List <ConditionStatementBlock> blocks = new List <ConditionStatementBlock>();

            blocks.Add(conditionStatementBlock);

            while (true)
            {
                var next = conditionStatementBlock.body.last.Next;
                if (!brs.Contains(next.Previous.OpCode))
                {
                    break;
                }
                var br     = next.Previous as Instruction;
                var target = br.Operand as Instruction;
                if (target.OpCode == OpCodes.Ret)
                {
                    break;
                }
                conditionStatementBlock = Detect(next, target.Previous);
                if (conditionStatementBlock == null)
                {
                    conditionStatementBlock = new ConditionStatementBlock(null, new CodeBlock(next, target.Previous));
                    blocks.Add(conditionStatementBlock);
                    break;
                }
                var current = blocks[blocks.Count - 1];
                blocks[blocks.Count - 1] = new ConditionStatementBlock(
                    current.condition,
                    new CodeBlock(current.body.first, current.body.last.Previous)
                    );
                blocks.Add(conditionStatementBlock);
            }

            CodeBlock all = new CodeBlock(block.first, blocks[blocks.Count - 1].body.last);

            statementStructure = new ConditionStatementStructure(all, blocks);
            return(true);
        }
Пример #2
0
 static public StatementStructureType Recognize(CodeBlock block, out StatementStructure statementStructure)
 {
     if (LoopStatementStructure.Detect(block, out statementStructure) ||
         ConditionStatementStructure.Detect(block, out statementStructure))
     {
         return(statementStructure.type);
     }
     statementStructure = null;
     return(StatementStructureType.Unknown);
 }
Пример #3
0
        static public bool Detect(CodeBlock block, out StatementStructure statementStructure)
        {
            statementStructure = null;
            var opCode = block.first.OpCode;

            if (opCode != OpCodes.Br && opCode != OpCodes.Br_S)
            {
                return(false);
            }

            // maybe loop condition
            var target = block.first.Operand as Instruction;

            // find next branch instruction (Brtrue, Brtrue_S), which may be a loop tag and an end
            Instruction last = null;

            {
                var tmp = target;
                while (tmp != null && !ConditionalBranch_OpCodes.Contains(tmp.OpCode))
                {
                    tmp = tmp.Next;
                }
                if (tmp == null)
                {
                    return(false);
                }
                last = tmp;
            }

            // loop body
            if ((last.Operand as Instruction).Previous != block.first)
            {
                return(false);
            }

            CodeBlock all       = new CodeBlock(block.first, last);
            CodeBlock init      = null;
            CodeBlock condition = new CodeBlock(target, last);
            CodeBlock step      = null;
            CodeBlock body      = new CodeBlock(block.first.Next, target.Previous);

            statementStructure = new LoopStatementStructure(all, init, condition, step, body);
            return(true);
        }
Пример #4
0
        public static Instruction Step(this Instruction current, Instruction last, CompileContext compileContext)
        {
            if (StatementStructure.Recognize(new CodeBlock(current, last), out StatementStructure statementStructure) != StatementStructureType.Unknown)
            {
                string s = statementStructure.Generate(compileContext);
                compileContext.WriteLine(s);
                return(statementStructure.all.last.Next);
            }
            uint?localVariableIndex = compileContext.GetLocalVariableInstructionIndex(current);

            if (localVariableIndex != null && compileContext.IsUnnecessaryLocalVariableID(localVariableIndex.Value))
            {
                return(current.Next.Next);
            }
            var code = current.OpCode.Code;

            if (!methods.TryGetValue(code, out MethodInfo method))
            {
                throw new Exception(string.Format("Unsupported operate code: {0}", code));
            }
            method.Invoke(null, new object[] { current, compileContext });
            return(current.Next);
        }