public void VisitCompilationUnit(CilCompilationUnit unit) { foreach (var child in unit.GetChildren()) { child.AcceptVisitor(this); } }
private void BindVariablesToSignatures(CilCompilationUnit unit) { foreach (var variable in unit.Variables) { _context.Variables.Add(variable, new VariableSignature(variable.VariableType)); } foreach (var parameter in unit.Parameters) { int cilIndex = parameter.ParameterIndex - (_context.MethodBody.Method.Signature.HasThis ? 1 : 0); ParameterSignature parameterSig; if (cilIndex == -1) { parameterSig = _context.MethodBody.ThisParameter; } else { parameterSig = _context.MethodBody.Method.Signature.Parameters[cilIndex]; parameterSig.ParameterType = parameter.VariableType; } _context.Parameters.Add(parameter, parameterSig); } }
private void CreateExceptionHandlers(CilCompilationUnit unit, CilInstructionCollection result) { foreach (var subGraph in unit.ControlFlowGraph.SubGraphs) { var ehFrame = (EHFrame)subGraph.UserData[EHFrame.EHFrameProperty]; CilExceptionHandlerType type; switch (ehFrame.Type) { case EHType.CATCH: type = CilExceptionHandlerType.Exception; break; case EHType.FILTER: type = CilExceptionHandlerType.Filter; break; case EHType.FAULT: type = CilExceptionHandlerType.Fault; break; case EHType.FINALLY: type = CilExceptionHandlerType.Finally; break; default: throw new ArgumentOutOfRangeException(); } // Find first and last nodes of try block. var tryBody = (ICollection <Node>)subGraph.UserData[ControlFlowGraph.TryBlockProperty]; var(tryStartNode, tryEndNode) = FindMinMaxNodes(tryBody); // Find first and last nodes of handler block. var handlerBody = (ICollection <Node>)subGraph.UserData[ControlFlowGraph.HandlerBlockProperty]; var(handlerStartNode, handlerEndNode) = FindMinMaxNodes(handlerBody); // Create handler. var handler = new CilExceptionHandler(); handler.HandlerType = type; handler.TryStart = new CilInstructionLabel(_blockEntries[tryStartNode]); handler.TryEnd = GetHandlerEndLabel(result, tryEndNode, "try"); handler.HandlerStart = new CilInstructionLabel(_blockEntries[handlerStartNode]); handler.HandlerEnd = GetHandlerEndLabel(result, handlerEndNode, "handler"); handler.ExceptionType = ehFrame.CatchType; if (ehFrame.Type == EHType.FILTER) { var filterStartNode = (Node)subGraph.UserData[ControlFlowGraph.FilterStartProperty]; handler.FilterStart = new CilInstructionLabel(_blockEntries[filterStartNode]); } _context.ExceptionHandlers.Add(ehFrame, handler); } }
private void CreateExceptionHandlers(CilCompilationUnit unit, CilInstructionCollection result) { foreach (var subGraph in unit.ControlFlowGraph.SubGraphs) { var ehFrame = (EHFrame)subGraph.UserData[EHFrame.EHFrameProperty]; ExceptionHandlerType type; switch (ehFrame.Type) { case EHType.CATCH: type = ExceptionHandlerType.Exception; break; case EHType.FILTER: type = ExceptionHandlerType.Filter; break; case EHType.FAULT: type = ExceptionHandlerType.Fault; break; case EHType.FINALLY: type = ExceptionHandlerType.Finally; break; default: throw new ArgumentOutOfRangeException(); } // Find first and last nodes of try block. var tryBody = (ICollection <Node>)subGraph.UserData[ControlFlowGraph.TryBlockProperty]; var(tryStartNode, tryEndNode) = FindMinMaxNodes(tryBody); // Find first and last nodes of handler block. var handlerBody = (ICollection <Node>)subGraph.UserData[ControlFlowGraph.HandlerBlockProperty]; var(handlerStartNode, handlerEndNode) = FindMinMaxNodes(handlerBody); // Create handler. var handler = new ExceptionHandler(type) { TryStart = _blockEntries[tryStartNode], TryEnd = result.GetByOffset(_blockExits[tryEndNode].Offset + _blockExits[tryEndNode].Size) ?? throw new CilCodeGeneratorException( $"Could not infer end of try block in {_context.MethodBody.Method.Name}."), HandlerStart = _blockEntries[handlerStartNode], HandlerEnd = result.GetByOffset(_blockExits[handlerEndNode].Offset + _blockExits[handlerEndNode].Size) ?? throw new CilCodeGeneratorException( $"Could not infer end of handler block in {_context.MethodBody.Method.Name}."), CatchType = ehFrame.CatchType }; _context.ExceptionHandlers.Add(ehFrame, handler); } }
public virtual bool VisitCompilationUnit(CilCompilationUnit unit) { bool changed = false; foreach (var node in unit.ControlFlowGraph.Nodes) { var block = (CilAstBlock)node.UserData[CilAstBlock.AstBlockProperty]; changed |= block.AcceptVisitor(this); } return(changed); }
public virtual bool ApplyTransformation(RecompilerContext context, CilCompilationUnit unit) { bool changed = false; while (unit.AcceptVisitor(this)) { changed = true; // Repeat until no more changes. } return(changed); }
public IList <CilInstruction> VisitCompilationUnit(CilCompilationUnit unit) { // Add variable signatures to the end result. BindVariablesToSignatures(unit); var result = GenerateInstructions(unit); var instructions = new CilInstructionCollection(_context.MethodBody); instructions.AddRange(result); instructions.CalculateOffsets(); CreateExceptionHandlers(unit, instructions); return(instructions); }
public CilMethodBody Compile(MethodDefinition method, CilCompilationUnit unit) { var methodBody = new CilMethodBody(method); var context = new CodeGenerationContext(methodBody, _constants, unit.FlagVariable, _flagHelperType); var cilGenerator = new CilCodeGenerator(context); context.CodeGenerator = cilGenerator; // Traverse and recompile the AST. methodBody.Instructions.AddRange(unit.AcceptVisitor(cilGenerator)); // Add variables to the method body. if (context.Variables.Count > 0) { foreach (var variable in context.Variables.Values) { methodBody.LocalVariables.Add(variable); } methodBody.InitializeLocals = true; } methodBody.Instructions.OptimizeMacros(); // Add all generated exception handlers to the method body. var handlers = context.ExceptionHandlers.Values.ToList(); handlers.Sort(new EHComparer()); foreach (var handler in handlers) { if (EnableExceptionHandlerValidation) { AssertValidityExceptionHandler(method, handler); } methodBody.ExceptionHandlers.Add(handler); } if (!EnableStackVerification) { methodBody.ComputeMaxStackOnBuild = false; methodBody.MaxStack = ushort.MaxValue; } return(methodBody); }
public override bool VisitCompilationUnit(CilCompilationUnit unit) { bool changed = false; // Go over each variable, and figure out the common base type of all the values that are assigned to it. // This is the new variable type. foreach (var variable in unit.Variables.Where(x => x.UsedBy.Count > 0)) { changed |= TryInferVariableType(variable); } foreach (var parameter in unit.Parameters.Where(x => x.UsedBy.Count > 0 && !x.HasFixedType)) { changed |= TryInferVariableType(parameter); } return(changed); }
private IList <CilInstruction> GenerateInstructions(CilCompilationUnit unit) { // Define block headers to use as branch targets later. foreach (var node in unit.ControlFlowGraph.Nodes) { _context.BlockHeaders[node] = CilInstruction.Create(CilOpCodes.Nop); } var generator = new BlockGenerator(unit.ControlFlowGraph, this); var rootScope = generator.CreateBlock(); var result = rootScope.GenerateInstructions(); _blockEntries = generator.BlockEntries; _blockExits = generator.BlockExits; return(result); }
private void BindVariablesToSignatures(CilCompilationUnit unit) { foreach (var variable in unit.Variables) { _context.Variables.Add(variable, new CilLocalVariable(variable.VariableType)); } foreach (var parameter in unit.Parameters) { var physicalParameter = _context.MethodBody.Owner.Parameters .GetBySignatureIndex(parameter.ParameterIndex); if (physicalParameter != _context.MethodBody.Owner.Parameters.ThisParameter) { physicalParameter.ParameterType = parameter.VariableType; } _context.Parameters.Add(parameter, physicalParameter); } }
public override bool ApplyTransformation(RecompilerContext context, CilCompilationUnit unit) { _context = context; return(base.ApplyTransformation(context, unit)); }
public void ApplyTransformation(RecompilerContext context, CilCompilationUnit unit) { _context = context; VisitCompilationUnit(unit); }
void ICilAstTransform.ApplyTransformation(RecompilerContext context, CilCompilationUnit unit) { ApplyTransformation(context, unit); }
public override bool ApplyTransformation(RecompilerContext context, CilCompilationUnit unit) { _context = context; _helper = new TypeHelper(context.ReferenceImporter); return(base.ApplyTransformation(context, unit)); }
public CilTransformEventArgs(CilCompilationUnit unit, ICilAstTransform transform) { Transform = transform; Unit = unit; }
public string VisitCompilationUnit(CilCompilationUnit unit) => "unit";