Exemplo n.º 1
0
        internal IIROperand Translate(IILASTNode node)
        {
            if (node is ILASTExpression expr)
            {
                try
                {
                    if (!handlers.TryGetValue(expr.ILCode, out ITranslationHandler handler))
                    {
                        throw new NotSupportedException(expr.ILCode.ToString());
                    }

                    int        i       = this.Instructions.Count;
                    IIROperand operand = handler.Translate(expr, this);
                    while (i < this.Instructions.Count)
                    {
                        this.Instructions[i].ILAST = expr;
                        i++;
                    }
                    return(operand);
                }
                catch (Exception ex)
                {
                    throw new Exception($"Failed to translate expr {expr.CILInstr} @ {expr.CILInstr.GetOffset():x4}.", ex);
                }
            }
            if (node is ILASTVariable)
            {
                return(this.Context.ResolveVRegister((ILASTVariable)node));
            }
            throw new NotSupportedException();
        }
Exemplo n.º 2
0
        internal IIROperand Translate(IILASTNode node)
        {
            if (node is ILASTExpression)
            {
                var expr = (ILASTExpression)node;
                try
                {
                    ITranslationHandler handler;
                    if (!handlers.TryGetValue(expr.ILCode, out handler))
                    {
                        throw new NotSupportedException(expr.ILCode.ToString());
                    }

                    var i       = Instructions.Count;
                    var operand = handler.Translate(expr, this);
                    while (i < Instructions.Count)
                    {
                        Instructions[i].ILAST = expr;
                        i++;
                    }
                    return(operand);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Failed to translate expr {0} @ {1:x4}.",
                                                      expr.CILInstr, expr.CILInstr.GetOffset()), ex);
                }
            }
            if (node is ILASTVariable)
            {
                return(Context.ResolveVRegister((ILASTVariable)node));
            }
            throw new NotSupportedException();
        }
Exemplo n.º 3
0
        private ILASTTree BuildAST(CILInstrList instrs, ILASTVariable[] beginStack)
        {
            var tree      = new ILASTTree();
            var evalStack = new Stack <ILASTVariable>(beginStack);
            Func <int, IILASTNode[]> popArgs = numArgs =>
            {
                var args = new IILASTNode[numArgs];
                for (int i = numArgs - 1; i >= 0; i--)
                {
                    args[i] = evalStack.Pop();
                }
                return(args);
            };

            var prefixes = new List <Instruction>();

            foreach (Instruction instr in instrs)
            {
                if (instr.OpCode.OpCodeType == OpCodeType.Prefix)
                {
                    prefixes.Add(instr);
                    continue;
                }

                int             pushes, pops;
                ILASTExpression expr;
                if (instr.OpCode.Code == Code.Dup)
                {
                    pushes = pops = 1;

                    ILASTVariable arg = evalStack.Peek();
                    expr = new ILASTExpression
                    {
                        ILCode    = Code.Dup,
                        Operand   = null,
                        Arguments = new IILASTNode[] { arg }
                    };
                }
                else
                {
                    instr.CalculateStackUsage(this.method.ReturnType.ElementType != ElementType.Void, out pushes, out pops);
                    Debug.Assert(pushes == 0 || pushes == 1);

                    if (pops == -1)
                    {
                        evalStack.Clear();
                        pops = 0;
                    }

                    expr = new ILASTExpression
                    {
                        ILCode    = instr.OpCode.Code,
                        Operand   = instr.Operand,
                        Arguments = popArgs(pops)
                    };
                    if (expr.Operand is Instruction || expr.Operand is Instruction[])
                    {
                        this.instrReferences.Add(expr);
                    }
                }
                expr.CILInstr = instr;
                if (prefixes.Count > 0)
                {
                    expr.Prefixes = prefixes.ToArray();
                    prefixes.Clear();
                }

                if (pushes == 1)
                {
                    var variable = new ILASTVariable
                    {
                        Name         = string.Format("s_{0:x4}", instr.Offset),
                        VariableType = ILASTVariableType.StackVar
                    };
                    evalStack.Push(variable);

                    tree.Add(new ILASTAssignment
                    {
                        Variable = variable,
                        Value    = expr
                    });
                }
                else
                {
                    tree.Add(expr);
                }
            }
            tree.StackRemains = evalStack.Reverse().ToArray();
            return(tree);
        }