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(); }
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(); }
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); }