private VBStyleCollection <BasicBlock, int> CreateBasicBlocks(short[] startblock, InstructionSequence instrseq, Dictionary <int, BasicBlock> mapInstrBlocks) { VBStyleCollection <BasicBlock, int> col = new VBStyleCollection <BasicBlock, int>(); InstructionSequence currseq = null; List <int> lstOffs = null; int len = startblock.Length; short counter = 0; int blockoffset = 0; BasicBlock currentBlock = null; for (int i = 0; i < len; i++) { if (startblock[i] == 1) { currentBlock = new BasicBlock(++counter); currseq = currentBlock.GetSeq(); lstOffs = currentBlock.GetInstrOldOffsets(); col.AddWithKey(currentBlock, currentBlock.id); blockoffset = instrseq.GetOffset(i); } startblock[i] = counter; Sharpen.Collections.Put(mapInstrBlocks, i, currentBlock); currseq.AddInstruction(instrseq.GetInstr(i), instrseq.GetOffset(i) - blockoffset); lstOffs.Add(instrseq.GetOffset(i)); } last_id = counter; return(col); }
public CreatedEmptyMethod(MethodDefDeclaration methodDeclaration, InstructionBlock principalBlock, LocalVariableSymbol returnVariable, InstructionSequence returnSequence) { this.MethodDeclaration = methodDeclaration; this.PrincipalBlock = principalBlock; this.ReturnVariable = returnVariable; this.ReturnSequence = returnSequence; }
protected override void ImplementOnException(InstructionBlock block, ITypeSignature exceptionType, InstructionWriter writer) { MethodDefDeclaration targetMethod = this.transformationInstance.AspectWeaverInstance.TargetElement as MethodDefDeclaration; if (targetMethod == null) { return; } // TODO: nested types string category = targetMethod.DeclaringType.Name; ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category); InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null); writer.AttachInstructionSequence(sequence); LocalVariableSymbol exceptionLocal = block.MethodBody.RootInstructionBlock.DefineLocalVariable( exceptionType, DebuggerSpecialNames.GetVariableSpecialName("ex")); LogSeverity logSeverity = LogSeverity.Warning; if (builder.SupportsIsEnabled) { builder.EmitGetIsEnabled(writer, logSeverity); InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence); writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence); } builder.EmitWrite(writer, block, "An exception occurred:\n{0}", 1, logSeverity, w => w.EmitInstructionLocalVariable(OpCodeNumber.Stloc, exceptionLocal), (i, w) => w.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, exceptionLocal)); writer.EmitInstruction(OpCodeNumber.Rethrow); writer.DetachInstructionSequence(); }
private bool ProcessSequence(InstructionSequence sequence, string extensionMethodName, Func <AutoPropertyInfo, Instruction> createInstruction) { for (var index = 0; index < sequence.Count; index++) { var instruction = sequence[index]; if (!instruction.IsExtensionMethodCall(extensionMethodName)) { continue; } if (sequence.Count < 4 || sequence[0].OpCode != OpCodes.Ldarg_0 || !sequence[1].IsPropertyGetterCall(out string?propertyName) || sequence.Skip(index + 1).Any(inst => inst?.OpCode != OpCodes.Nop) || !_autoPropertyToBackingFieldMap.TryGetValue(propertyName, out var propertyInfo)) { var message = $"Invalid usage of extension method '{extensionMethodName}()': '{extensionMethodName}()' is only valid on auto-properties of class {_method.DeclaringType?.Name}"; _logger.LogError(message, sequence.Point); return(false); } _logger.LogInfo($"Replace {extensionMethodName}() on property {propertyName} in method {_method}."); sequence[index] = createInstruction(propertyInfo !); sequence.RemoveAt(1); return(true); } return(true); }
private MethodDefDeclaration CreateTraceStringFormatWrapper(string name) { MethodDefDeclaration formatWrapperMethod = new MethodDefDeclaration { Name = name, Attributes = MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, }; this.implementationType.Methods.Add(formatWrapperMethod); formatWrapperMethod.Parameters.Add(new ParameterDeclaration(0, "format", this.module.Cache.GetIntrinsic(IntrinsicType.String))); formatWrapperMethod.Parameters.Add(new ParameterDeclaration(1, "args", this.module.Cache.GetType(typeof(object[])))); InstructionBlock block = formatWrapperMethod.MethodBody.CreateInstructionBlock(); formatWrapperMethod.MethodBody.RootInstructionBlock = block; InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null); this.writer.AttachInstructionSequence(sequence); for (int i = 0; i < formatWrapperMethod.Parameters.Count; i++) { this.writer.EmitInstructionInt16(OpCodeNumber.Ldarg, (short)i); } this.writer.EmitInstructionMethod(OpCodeNumber.Call, this.stringFormatArrayMethod); this.EmitCallHandler(this.traceWriteLineMethod); this.writer.EmitInstruction(OpCodeNumber.Ret); this.writer.DetachInstructionSequence(); return(formatWrapperMethod); }
private void EmitMessage(InstructionBlock block, InstructionWriter writer, MethodDefDeclaration targetMethod, string messageFormatString) { // TODO: nested types string category = targetMethod.DeclaringType.Name; ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category); InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null); writer.AttachInstructionSequence(sequence); if (builder.SupportsIsEnabled) { builder.EmitGetIsEnabled(writer, LogSeverity.Trace); InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence); writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence); } int parameterCount = Context.MethodMapping.MethodSignature.ParameterCount; bool hasThis = Context.MethodMapping.MethodSignature.CallingConvention == CallingConvention.HasThis; builder.EmitWrite(writer, block, messageFormatString, parameterCount, LogSeverity.Trace, null, (i, instructionWriter) => { instructionWriter.EmitInstructionInt16(OpCodeNumber.Ldarg, (short)(hasThis ? i + 1 : i)); instructionWriter.EmitConvertToObject( this.Context.MethodMapping.MethodSignature.GetParameterType(i)); }); writer.DetachInstructionSequence(); }
public static void RedirectBranchInstructions(this InstructionBlock block, InstructionReader reader, InstructionWriter writer, InstructionSequence branchTargetSequence, Predicate<Instruction> predicate) { if (block.HasChildrenBlocks) { for (InstructionBlock block1 = block.FirstChildBlock; block1 != null; block1 = block1.NextSiblingBlock) { if (!block1.HasExceptionHandlers) RedirectBranchInstructions(block1, reader, writer, branchTargetSequence, predicate); } } reader.JumpToInstructionBlock(block); if (block.HasInstructionSequences) { for (InstructionSequence sequence = block.FirstInstructionSequence; sequence != null; sequence = sequence.NextSiblingSequence) { bool commit = false; writer.AttachInstructionSequence(sequence); reader.EnterInstructionSequence(sequence); while (reader.ReadInstruction()) { var opCode = reader.CurrentInstruction.OpCodeNumber; var opCodeInfo = reader.CurrentInstruction.OpCodeInfo; if ((opCodeInfo.FlowControl == FlowControl.Branch || opCodeInfo.FlowControl == FlowControl.Cond_Branch) && (predicate == null || predicate(reader.CurrentInstruction))) { commit = true; writer.EmitBranchingInstruction(opCode, branchTargetSequence); } else { reader.CurrentInstruction.Write(writer); } } reader.LeaveInstructionSequence(); writer.DetachInstructionSequence(commit); } } reader.LeaveInstructionBlock(); }
private static void AddHelloWorldToMethod(MethodDefDeclaration targetMethod, IMethod consoleWriteLine) { // Removes the original code from the method body. Without this, you would get exceptions: InstructionBlock originalCode = targetMethod.MethodBody.RootInstructionBlock; originalCode.Detach(); // Replaces the method body's content: InstructionBlock root = targetMethod.MethodBody.CreateInstructionBlock(); targetMethod.MethodBody.RootInstructionBlock = root; InstructionBlock helloWorldBlock = root.AddChildBlock(); InstructionSequence helloWorldSequence = helloWorldBlock.AddInstructionSequence(); using (var writer = InstructionWriter.GetInstance()) { // Add instructions to the beginning of the method body: writer.AttachInstructionSequence(helloWorldSequence); // Say that what follows is compiler-generated code: writer.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden); // Emit a call to Console.WriteLine("Hello, world!"): writer.EmitInstructionString(OpCodeNumber.Ldstr, "Hello, world!"); writer.EmitInstructionMethod(OpCodeNumber.Call, consoleWriteLine); writer.DetachInstructionSequence(); } // Re-adding the original code at the end: root.AddChildBlock(originalCode); }
private void SetExceptionEdges(InstructionSequence instrseq, Dictionary <int, BasicBlock > instrBlocks) { exceptions = new List <ExceptionRangeCFG>(); Dictionary <string, ExceptionRangeCFG> mapRanges = new Dictionary <string, ExceptionRangeCFG >(); foreach (ExceptionHandler handler in instrseq.GetExceptionTable().GetHandlers()) { BasicBlock from = instrBlocks.GetOrNull(handler.from_instr); BasicBlock to = instrBlocks.GetOrNull(handler.to_instr); BasicBlock handle = instrBlocks.GetOrNull(handler.handler_instr); string key = from.id + ":" + to.id + ":" + handle.id; if (mapRanges.ContainsKey(key)) { ExceptionRangeCFG range = mapRanges.GetOrNull(key); range.AddExceptionType(handler.exceptionClass); } else { List <BasicBlock> protectedRange = new List <BasicBlock>(); for (int j = from.id; j < to.id; j++) { BasicBlock block = blocks.GetWithKey(j); protectedRange.Add(block); block.AddSuccessorException(handle); } ExceptionRangeCFG range = new ExceptionRangeCFG(protectedRange, handle, handler.exceptionClass == null ? null : System.Linq.Enumerable.ToList(new [] { handler.exceptionClass }) ); Sharpen.Collections.Put(mapRanges, key, range); exceptions.Add(range); } } }
private static short[] FindStartInstructions(InstructionSequence seq) { int len = seq.Length(); short[] inststates = new short[len]; HashSet <int> excSet = new HashSet <int>(); foreach (ExceptionHandler handler in seq.GetExceptionTable().GetHandlers()) { excSet.Add(handler.from_instr); excSet.Add(handler.to_instr); excSet.Add(handler.handler_instr); } for (int i = 0; i < len; i++) { // exception blocks if (excSet.Contains(i)) { inststates[i] = 1; } Instruction instr = seq.GetInstr(i); switch (instr.group) { case Group_Jump: { inststates[((JumpInstruction)instr).destination] = 1; goto case Group_Return; } case Group_Return: { if (i + 1 < len) { inststates[i + 1] = 1; } break; } case Group_Switch: { SwitchInstruction swinstr = (SwitchInstruction)instr; int[] dests = swinstr.GetDestinations(); for (int j = dests.Length - 1; j >= 0; j--) { inststates[dests[j]] = 1; } inststates[swinstr.GetDefaultDestination()] = 1; if (i + 1 < len) { inststates[i + 1] = 1; } break; } } } // first instruction inststates[0] = 1; return(inststates); }
public void Emit(InstructionWriter writer, InstructionBlock block, TypeInitializationClientScopes scope) { InstructionSequence sequence = block.AddInstructionSequence(); writer.AttachInstructionSequence(sequence); writer.EmitInstructionMethod(OpCodeNumber.Call, attachMethod); writer.DetachInstructionSequence(); }
public virtual void ReleaseResources() { if (containsCode__ && expanded) { seq = null; expanded = false; } }
private static void RemoveJsrInstructions(ConstantPool pool, BasicBlock block, DataPoint data) { ListStack <VarType> stack = data.GetStack(); InstructionSequence seq = block.GetSeq(); for (int i = 0; i < seq.Length(); i++) { Instruction instr = seq.GetInstr(i); VarType var = null; if (instr.opcode == ICodeConstants.opc_astore || instr.opcode == ICodeConstants.opc_pop) { var = stack.GetByOffset(-1); } InstructionImpact.StepTypes(data, instr, pool); switch (instr.opcode) { case ICodeConstants.opc_jsr: case ICodeConstants.opc_ret: { seq.RemoveInstruction(i); i--; break; } case ICodeConstants.opc_astore: case ICodeConstants.opc_pop: { if (var.type == ICodeConstants.Type_Address) { seq.RemoveInstruction(i); i--; } break; } } } block.mark = 1; for (int i = 0; i < block.GetSuccs().Count; i++) { BasicBlock suc = block.GetSuccs()[i]; if (suc.mark != 1) { RemoveJsrInstructions(pool, suc, data.Copy()); } } for (int i = 0; i < block.GetSuccExceptions().Count; i++) { BasicBlock suc = block.GetSuccExceptions()[i]; if (suc.mark != 1) { DataPoint point = new DataPoint(); point.SetLocalVariables(new List <VarType>(data.GetLocalVariables())); point.GetStack().Push(new VarType(ICodeConstants.Type_Object, 0, null)); RemoveJsrInstructions(pool, suc, point); } } }
public virtual void BuildMonitorFlags() { foreach (Statement st in stats) { st.BuildMonitorFlags(); } switch (type) { case Type_Basicblock: { BasicBlockStatement bblock = (BasicBlockStatement)this; InstructionSequence seq = bblock.GetBlock().GetSeq(); if (seq != null && seq.Length() > 0) { for (int i = 0; i < seq.Length(); i++) { if (seq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit) { containsMonitorExit = true; break; } } isMonitorEnter__ = (seq.GetLastInstr().opcode == ICodeConstants.opc_monitorenter); } break; } case Type_Sequence: case Type_If: { containsMonitorExit = false; foreach (Statement st in stats) { containsMonitorExit |= st.IsContainsMonitorExit(); } break; } case Type_Syncronized: case Type_Root: case Type_General: { break; } default: { containsMonitorExit = false; foreach (Statement st in stats) { containsMonitorExit |= st.IsContainsMonitorExit(); } break; } } }
private void EmitContstructorBlock(MethodDefDeclaration staticConstructor) { this.constructorBlock = staticConstructor.MethodBody.RootInstructionBlock = staticConstructor.MethodBody.CreateInstructionBlock(); this.returnSequence = staticConstructor.MethodBody.RootInstructionBlock.AddInstructionSequence(null, NodePosition.After, null); this.writer.AttachInstructionSequence(this.returnSequence); this.writer.EmitInstruction(OpCodeNumber.Ret); this.writer.DetachInstructionSequence(); }
/// <exception cref="System.IO.IOException"/> public virtual void ExpandData() { if (containsCode__ && !expanded) { byte[] code = classStruct.GetLoader().LoadBytecode(this, codeFullLength); seq = ParseBytecode(new DataInputFullStream(code), codeLength, classStruct.GetPool ()); expanded = true; } }
public void Weave(WeavingContext context, InstructionBlock block) { IMethod oldOperand = context.InstructionReader.CurrentInstruction.MethodOperand; InstructionSequence sequence = block.MethodBody.CreateInstructionSequence(); block.AddInstructionSequence(sequence); context.InstructionWriter.AttachInstructionSequence(sequence); context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Callvirt, oldOperand); context.InstructionWriter.DetachInstructionSequence(); }
public ControlFlowGraph(InstructionSequence seq) { // ***************************************************************************** // private fields // ***************************************************************************** // ***************************************************************************** // constructors // ***************************************************************************** BuildBlocks(seq); }
void IAdvice.Weave(WeavingContext context, InstructionBlock block) { Console.WriteLine("Weave"); IMethod method = this.methods[context.JoinPoint.Instruction.OpCodeNumber]; InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null); context.InstructionWriter.AttachInstructionSequence(sequence); context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Call, method); context.InstructionWriter.DetachInstructionSequence(); }
//return ranges.isEmpty() ? null : ranges; // public String getExceptionsUniqueString(BasicBlock handler, BasicBlock block) { // // List<ExceptionRangeCFG> ranges = getExceptionRange(handler, block); // // if(ranges == null) { // return null; // } else { // Set<String> setExceptionStrings = new HashSet<String>(); // for(ExceptionRangeCFG range : ranges) { // setExceptionStrings.add(range.getExceptionType()); // } // // String ret = ""; // for(String exception : setExceptionStrings) { // ret += exception; // } // // return ret; // } // } // ***************************************************************************** // private methods // ***************************************************************************** private void BuildBlocks(InstructionSequence instrseq) { short[] states = FindStartInstructions(instrseq); Dictionary <int, BasicBlock> mapInstrBlocks = new Dictionary <int, BasicBlock>(); VBStyleCollection <BasicBlock, int> colBlocks = CreateBasicBlocks(states, instrseq , mapInstrBlocks); blocks = colBlocks; ConnectBlocks(colBlocks, mapInstrBlocks); SetExceptionEdges(instrseq, mapInstrBlocks); SetSubroutineEdges(); SetFirstAndLastBlocks(); }
public static void MergeBasicBlocks(ControlFlowGraph graph) { while (true) { bool merged = false; foreach (BasicBlock block in graph.GetBlocks()) { InstructionSequence seq = block.GetSeq(); if (block.GetSuccs().Count == 1) { BasicBlock next = block.GetSuccs()[0]; if (next != graph.GetLast() && (seq.IsEmpty() || seq.GetLastInstr().group != ICodeConstants .Group_Switch)) { if (next.GetPreds().Count == 1 && (next.GetPredExceptions().Count == 0) && next != graph.GetFirst()) { // TODO: implement a dummy start block bool sameRanges = true; foreach (ExceptionRangeCFG range in graph.GetExceptions()) { if (range.GetProtectedRange().Contains(block) ^ range.GetProtectedRange().Contains (next)) { sameRanges = false; break; } } if (sameRanges) { seq.AddSequence(next.GetSeq()); Sharpen.Collections.AddAll(block.GetInstrOldOffsets(), next.GetInstrOldOffsets()); next.GetSeq().Clear(); RemoveEmptyBlock(graph, next, true); merged = true; break; } } } } } if (!merged) { break; } } }
static void Main(string[] args) { var expressionManager = new InstructionSequence(); var rd3s = Radh3aParser.Parse(@"D:\radh3a.txt"); foreach (var rd3 in rd3s) { if (rd3 == "rd3.rd3?") { expressionManager.Add(new MovePointerForwardInstruction()); } else if (rd3 == "rd3?rd3.") { expressionManager.Add(new MovePointerBackwardInstruction()); } else if (rd3 == "rd3.rd3.") { expressionManager.Add(new IncrementCellInstruction()); } else if (rd3 == "rd3!rd3!") { expressionManager.Add(new DecrementCellInstruction()); } else if (rd3 == "rd3.rd3!") { expressionManager.Add(new ReadCharInstruction()); } else if (rd3 == "rd3!rd3.") { expressionManager.Add(new PrintCharInstruction()); } else if (rd3 == "rd3!rd3?") { expressionManager.Add(new MoveForwardToWhenZeroInstruction(expressionManager)); } else if (rd3 == "rd3?rd3!") { expressionManager.Add(new MoveBackwardToIfNotZeroInstruction(expressionManager)); } } expressionManager.Run(); Console.ReadLine(); }
private TypeDefDeclaration CreateContainingType() { string uniqueName = this.module.Types.GetUniqueName( DebuggerSpecialNames.GetDeclarationSpecialName("LoggingImplementationDetails{0}")); TypeDefDeclaration logCategoriesType = new TypeDefDeclaration { Name = uniqueName, Attributes = TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.Abstract, BaseType = ((IType)this.module.Cache.GetType("System.Object, mscorlib")) }; this.module.Types.Add(logCategoriesType); // Add [CompilerGenerated] and [DebuggerNonUserCode] to the type this.weavingHelper.AddCompilerGeneratedAttribute(logCategoriesType.CustomAttributes); this.weavingHelper.AddDebuggerNonUserCodeAttribute(logCategoriesType.CustomAttributes); MethodDefDeclaration staticConstructor = new MethodDefDeclaration { Name = ".cctor", Attributes = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName | MethodAttributes.HideBySig, }; logCategoriesType.Methods.Add(staticConstructor); staticConstructor.ReturnParameter = new ParameterDeclaration { Attributes = ParameterAttributes.Retval, ParameterType = this.module.Cache.GetIntrinsic(IntrinsicType.Void) }; this.constructorBlock = staticConstructor.MethodBody.RootInstructionBlock = staticConstructor.MethodBody.CreateInstructionBlock(); this.returnSequence = staticConstructor.MethodBody.RootInstructionBlock.AddInstructionSequence(null, NodePosition.After, null); this.writer.AttachInstructionSequence(this.returnSequence); this.writer.EmitInstruction(OpCodeNumber.Ret); this.writer.DetachInstructionSequence(); return(logCategoriesType); }
/// <summary> /// Emits: /// <code> /// brfalse elseBranch; /// thenStatement(); /// br end; /// elseBranch: /// elseStatement(); /// end: /// </code> /// </summary> public static void IfNotZero(this InstructionWriter writer, Action <InstructionWriter> thenStatement, Action <InstructionWriter> elseStatement) { InstructionSequence elseSequence = writer.CurrentInstructionSequence.ParentInstructionBlock.AddInstructionSequence(); InstructionSequence endSequence = writer.CurrentInstructionSequence.ParentInstructionBlock.AddInstructionSequence(); writer.EmitBranchingInstruction(OpCodeNumber.Brfalse, elseSequence); thenStatement(writer); writer.EmitBranchingInstruction(OpCodeNumber.Br, endSequence); writer.DetachInstructionSequence(); writer.AttachInstructionSequence(elseSequence); elseStatement(writer); writer.EmitBranchingInstruction(OpCodeNumber.Br, endSequence); writer.DetachInstructionSequence(); writer.AttachInstructionSequence(endSequence); }
/// <summary> /// Creates a new method body and assigns it to <paramref name="hostMethod"/>. The method body looks as described in <see cref="CreatedEmptyMethod"/>. /// </summary> /// <param name="instructionWriter">A <b>detached</b> instruction writer.</param> /// <param name="hostMethod">The method without body. The body will be assigned to this method.</param> /// <returns>References to points in the method body.</returns> public static CreatedEmptyMethod CreateModifiableMethodBody(InstructionWriter instructionWriter, MethodDefDeclaration hostMethod) { // Create a new method body to host the pipeline. hostMethod.MethodBody = new MethodBodyDeclaration(); InstructionBlock rootInstructionBlock = hostMethod.MethodBody.RootInstructionBlock = hostMethod.MethodBody.CreateInstructionBlock(); InstructionBlock sequencePointBlock = rootInstructionBlock.AddChildBlock(); InstructionSequence sequencePointSequence = sequencePointBlock.AddInstructionSequence(); instructionWriter.AttachInstructionSequence(sequencePointSequence); instructionWriter.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden); instructionWriter.EmitInstruction(OpCodeNumber.Nop); instructionWriter.DetachInstructionSequence(); InstructionBlock implementationBlock = rootInstructionBlock.AddChildBlock(); InstructionBlock returnBlock = rootInstructionBlock.AddChildBlock(); InstructionSequence returnSequence = returnBlock.AddInstructionSequence(); instructionWriter.AttachInstructionSequence(returnSequence); instructionWriter.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden); LocalVariableSymbol returnVariable; if (!hostMethod.ReturnParameter.ParameterType.IsIntrinsic(IntrinsicType.Void)) { hostMethod.MethodBody.InitLocalVariables = true; returnVariable = rootInstructionBlock.DefineLocalVariable( hostMethod.ReturnParameter.ParameterType, DebuggerSpecialNames.GetVariableSpecialName(hostMethod.Domain, "returnValue", DebuggerSpecialVariableKind.ReturnValue) ); instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, returnVariable); } else { returnVariable = null; } instructionWriter.EmitInstruction(OpCodeNumber.Ret); instructionWriter.DetachInstructionSequence(); return(new CreatedEmptyMethod(hostMethod, implementationBlock, returnVariable, returnSequence)); }
private static void RemoveExceptionInstructionsEx(BasicBlock block, int blocktype , int finallytype) { InstructionSequence seq = block.GetSeq(); if (finallytype == 3) { // empty finally handler for (int i = seq.Length() - 1; i >= 0; i--) { seq.RemoveInstruction(i); } } else { if ((blocktype & 1) > 0) { // first if (finallytype == 2 || finallytype == 1) { // astore or pop seq.RemoveInstruction(0); } } if ((blocktype & 2) > 0) { // last if (finallytype == 2 || finallytype == 0) { seq.RemoveLast(); } if (finallytype == 2) { // astore seq.RemoveLast(); } } } }
/// <summary> /// Emits: /// <code> /// br begin; /// begin: /// condition(); /// brfalse end; /// body(); /// br begin; /// end: /// </code> /// </summary> public static void WhileNotZero(this InstructionWriter writer, Action <InstructionWriter> condition, Action <InstructionWriter> body) { InstructionSequence loopBegin = writer.CurrentInstructionSequence.ParentInstructionBlock.AddInstructionSequence(); InstructionSequence loopEnd = writer.CurrentInstructionSequence.ParentInstructionBlock.AddInstructionSequence(); writer.EmitBranchingInstruction(OpCodeNumber.Br, loopBegin); writer.DetachInstructionSequence(); writer.AttachInstructionSequence(loopBegin); condition(writer); writer.EmitBranchingInstruction(OpCodeNumber.Brfalse, loopEnd); body(writer); writer.EmitBranchingInstruction(OpCodeNumber.Br, loopBegin); writer.DetachInstructionSequence(); writer.AttachInstructionSequence(loopEnd); }
private FieldDefDeclaration CreateCategoryField(ITypeSignature fieldType, Action <InstructionWriter> initializeFieldAction) { string fieldName = string.Format("l{0}", this.containingType.Fields.Count + 1); FieldDefDeclaration loggerFieldDef = new FieldDefDeclaration { Name = fieldName, Attributes = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly, FieldType = fieldType }; this.containingType.Fields.Add(loggerFieldDef); InstructionSequence sequence = this.constructorBlock.AddInstructionSequence(null, NodePosition.Before, this.returnSequence); this.writer.AttachInstructionSequence(sequence); initializeFieldAction(this.writer); this.writer.EmitInstructionField(OpCodeNumber.Stsfld, loggerFieldDef); this.writer.DetachInstructionSequence(); return(loggerFieldDef); }
/// <summary> /// Emits the MSIL code that jumps to the specified label if logging is disabled. /// </summary> /// <param name="emitter">IL emitter.</param> /// <param name="logLevelSupportItem">Item for the logging level.</param> /// <param name="perTypeLoggingData">Data for the type being woven.</param> /// <param name="afterLoggingSequence">Sequence to jump to if logging is disabled.</param> /// <exception cref="ArgumentNullException"><paramref name="emitter"/>, <paramref name="logLevelSupportItem"/>, <paramref name="perTypeLoggingData"/> or <paramref name="afterLoggingSequence"/> is <see langword="null"/>.</exception> /// <remarks> /// <para>Code emitted by this method makes no assumptions on the state of the evaluation stack /// and it leaves the stack unmodified.</para> /// </remarks> private static void EmitLoggingEnabledCheck(InstructionWriter emitter, LogLevelSupportItem logLevelSupportItem, PerTypeLoggingData perTypeLoggingData, InstructionSequence afterLoggingSequence) { if (emitter == null) { throw new ArgumentNullException("emitter"); } if (logLevelSupportItem == null) { throw new ArgumentNullException("logLevelSupportItem"); } if (perTypeLoggingData == null) { throw new ArgumentNullException("perTypeLoggingData"); } if (afterLoggingSequence == null) { throw new ArgumentNullException("afterLoggingSequence"); } emitter.EmitInstructionField(OpCodeNumber.Ldsfld, GenericHelper.GetCanonicalGenericInstance(perTypeLoggingData.Log)); emitter.EmitInstructionMethod(OpCodeNumber.Callvirt, logLevelSupportItem.IsLoggingEnabledGetter); emitter.EmitInstruction(OpCodeNumber.Ldc_I4_0); emitter.EmitInstruction(OpCodeNumber.Ceq); emitter.EmitBranchingInstruction(OpCodeNumber.Brtrue_S, afterLoggingSequence); }
public void LeaveInstructionSequence(InstructionSequence instructionSequence) { }
public void EnterInstructionSequence(InstructionSequence instructionSequence) { }
private void EmitMessage(InstructionBlock block, InstructionWriter writer, LogLevel logLevel, string messageFormatString, int[] arguments, ITypeSignature exceptionType = null) { MethodDefDeclaration targetMethod = Context.TargetElement as MethodDefDeclaration; if (targetMethod == null) { return; } // TODO: nested types string category = targetMethod.DeclaringType.Name; ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category); InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null); writer.AttachInstructionSequence(sequence); LocalVariableSymbol exceptionLocal = null; if (exceptionType != null) { exceptionLocal = block.MethodBody.RootInstructionBlock.DefineLocalVariable( exceptionType, DebuggerSpecialNames.GetVariableSpecialName("ex")); } if (builder.SupportsIsEnabled) { builder.EmitGetIsEnabled(writer, logLevel); InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence); writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence); } bool useWrapper = ShouldUseWrapper(targetMethod); Action <InstructionWriter> getExceptionAction = exceptionLocal != null ? (Action <InstructionWriter>)(w => w.EmitInstructionLocalVariable(OpCodeNumber.Stloc, exceptionLocal)) : null; builder.EmitWrite(writer, messageFormatString, exceptionType == null ? arguments.Length : arguments.Length + 1, logLevel, getExceptionAction, (i, instructionWriter) => { if (i < arguments.Length) { int index = arguments[i]; if (index == MessageArgumentsFormatter.ThisArgumentPosition) { this.methodMappingWriter.EmitLoadInstance(false, instructionWriter); } else if (index == MessageArgumentsFormatter.ReturnParameterPosition) { instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, Context.ReturnValueVariable); instructionWriter.EmitConvertToObject( Context.MethodMapping.MethodSignature.ReturnType); } else { this.methodMappingWriter.EmitLoadArgument(index, instructionWriter); instructionWriter.EmitConvertToObject(this.methodMappingWriter.MethodMapping.MethodSignature.GetParameterType(index).GetNakedType(TypeNakingOptions.IgnoreManagedPointers)); } } else { //Emit exception parameter instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, exceptionLocal); } }, useWrapper); if (exceptionType == null) { writer.DetachInstructionSequence(); } }
public static void Leave_IfTrue(this InstructionWriter instructionWriter, InstructionSequence leaveTarget) { instructionWriter.EmitBranchingInstruction(OpCodeNumber.Brtrue, leaveTarget); }
public static void RedirectBranchInstructions(this InstructionBlock block, InstructionReader reader, InstructionWriter writer, InstructionSequence branchTargetSequence) { RedirectBranchInstructions(block, reader, writer, branchTargetSequence, null); }
public InstructionSequenceTreeNode( InstructionSequence sequence ) : base( TreeViewImage.Field, sequence ) { this.Text = sequence.ToString(); }
public void LeaveInstructionSequence(InstructionSequence instructionSequence) { }
public void EnterInstructionSequence(InstructionSequence instructionSequence) { }
/// <summary> /// Emits instruction that invoke <b>InitializeAspects</b>. /// </summary> /// <param name="initializeMethodDef">The <b>InitializeAspects</b> method.</param> /// <param name="sequence"><see cref="InstructionSequence"/> where instructions have to be emitted.</param> /// <param name="writer">The <see cref="InstructionWriter"/> to be used.</param> private static void EmitCallInitialize( MethodDefDeclaration initializeMethodDef, InstructionSequence sequence, InstructionWriter writer ) { writer.AttachInstructionSequence( sequence ); writer.EmitSymbolSequencePoint( SymbolSequencePoint.Hidden ); writer.EmitInstruction( OpCodeNumber.Ldarg_0 ); writer.EmitInstructionMethod( OpCodeNumber.Callvirt, GenericHelper.GetMethodCanonicalGenericInstance( initializeMethodDef ) ); writer.DetachInstructionSequence(); }
private void EmitContstructorBlock( MethodDefDeclaration staticConstructor ) { this.constructorBlock = staticConstructor.MethodBody.RootInstructionBlock = staticConstructor.MethodBody.CreateInstructionBlock(); this.returnSequence = staticConstructor.MethodBody.RootInstructionBlock.AddInstructionSequence( null, NodePosition.After, null ); this.writer.AttachInstructionSequence( this.returnSequence ); this.writer.EmitInstruction( OpCodeNumber.Ret ); this.writer.DetachInstructionSequence(); }
private TypeDefDeclaration CreateContainingType() { string uniqueName = this.module.Types.GetUniqueName( DebuggerSpecialNames.GetDeclarationSpecialName("LoggingImplementationDetails{0}")); TypeDefDeclaration logCategoriesType = new TypeDefDeclaration { Name = uniqueName, Attributes = TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.Abstract, BaseType = ((IType)this.module.Cache.GetType("System.Object, mscorlib")) }; this.module.Types.Add(logCategoriesType); // Add [CompilerGenerated] and [DebuggerNonUserCode] to the type this.weavingHelper.AddCompilerGeneratedAttribute(logCategoriesType.CustomAttributes); this.weavingHelper.AddDebuggerNonUserCodeAttribute(logCategoriesType.CustomAttributes); MethodDefDeclaration staticConstructor = new MethodDefDeclaration { Name = ".cctor", Attributes = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName | MethodAttributes.HideBySig, }; logCategoriesType.Methods.Add(staticConstructor); staticConstructor.ReturnParameter = new ParameterDeclaration { Attributes = ParameterAttributes.Retval, ParameterType = this.module.Cache.GetIntrinsic(IntrinsicType.Void) }; this.constructorBlock = staticConstructor.MethodBody.RootInstructionBlock = staticConstructor.MethodBody.CreateInstructionBlock(); this.returnSequence = staticConstructor.MethodBody.RootInstructionBlock.AddInstructionSequence(null, NodePosition.After, null); this.writer.AttachInstructionSequence(this.returnSequence); this.writer.EmitInstruction(OpCodeNumber.Ret); this.writer.DetachInstructionSequence(); return logCategoriesType; }