|
|
|
Community Member
|
|
I now mapped the IL in PostSharp 1:1, but I am getting the following error during compilation:
Unhandled exception: System.IndexOutOfRangeException: Index was outside the bounds of the array. at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 278 at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 199 at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 199 at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 199 at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 199 at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 199 at PostSharp.ModuleWriter.PreparingInstructionEmitter.ProcessBlock(InstructionBlock block) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 199 at PostSharp.ModuleWriter.PreparingInstructionEmitter.Prepare(AddressRange[]& instructionSequenceRanges, Boolean[]& localVariableHasMissingSymbol, Boolean[]& localVariableHasReference) in p:\branches\1.5\Core\PostSharp.Core\ModuleWriter\PreparingInstructionEmitter.cs:line 163 at PostSharp.CodeModel.MethodBodyDeclaration.WriteILDefinition(ILWriter writer) in p:\branches\1.5\Core\PostSharp.Core\CodeModel\MethodBodyDeclaration.cs:line 518 at PostSharp.CodeModel.MethodDefDeclaration.WriteILDefinition(ILWriter writer, GenericMap genericMap) in p:\branches\1.5\Core\PostSharp.Core\CodeModel\MethodDefDeclaration.cs:line 1310 at PostSharp.CodeModel.TypeDefDeclaration.WriteILDefinition(ILWriter writer) in p:\branches\1.5\Core\PostSharp.Core\CodeModel\TypeDefDeclaration.cs:line 1207 at PostSharp.CodeModel.ModuleDeclaration.WriteILDefinition(ILWriter writer) in p:\branches\1.5\Core\PostSharp.Core\CodeModel\ModuleDeclaration.cs:line 706 at PostSharp.Extensibility.Tasks.CompileTask.Execute() in p:\branches\1.5\Core\PostSharp.Core\Extensibility\Tasks\CompileTask.cs:line 451 at PostSharp.Extensibility.Project.ExecutePhase(String phase) in p:\branches\1.5\Core\PostSharp.Core\Extensibility\Project.cs:line 1224 at PostSharp.Extensibility.Project.Execute() in p:\branches\1.5\Core\PostSharp.Core\Extensibility\Project.cs:line 1267 at PostSharp.Extensibility.PostSharpObject.ExecuteProjects() in p:\branches\1.5\Core\PostSharp.Core\Extensibility\PostSharpObject.cs:line 616 at PostSharp.Extensibility.PostSharpObject.InvokeProject(ProjectInvocation projectInvocation) in p:\branches\1.5\Core\PostSharp.Core\Extensibility\PostSharpObject.cs:line 547 at PostSharp.MSBuild.PostSharpRemoteTask.Execute(PostSharpTaskParameters parameters, TaskLoggingHelper log) in p:\branches\1.5\Core\PostSharp.MSBuild\PostSharpRemoteTask.cs:line 113 HK.Logging.Tests
The IL I want to replicate looks like this:
L_0002: ldstr "Category" L_0007: ldstr "Tracing" L_000c: ldstr "TracedMethod(string)" L_0011: ldc.i4.1 L_0012: newarr [HK.Logging]HK.Logging.NameAndValue L_0017: stloc.0 L_0018: ldloc.0 L_0019: ldc.i4.0 L_001a: ldstr "param1" L_001f: ldarg.1 L_0020: newobj instance void [HK.Logging]HK.Logging.NameAndValue::.ctor(string, string) L_0025: stelem.ref L_0026: ldloc.0 L_0027: call void [HK.Logging]HK.Logging.Log::MethodEntry(string, string, string, class [HK.Logging]HK.Logging.NameAndValue[])
The mapped PostSharp code looks like this:
writer.EmitInstructionString(OpCodeNumber.Ldstr, "Category"); writer.EmitInstructionString(OpCodeNumber.Ldstr, "Tracing"); writer.EmitInstructionString(OpCodeNumber.Ldstr, "TracedMethod"); writer.EmitInstruction(OpCodeNumber.Ldc_I4_1); writer.EmitInstructionType(OpCodeNumber.Newarr, _task.NameAndValueType); writer.EmitInstruction(OpCodeNumber.Stloc_0); writer.EmitInstruction(OpCodeNumber.Ldloc_0); writer.EmitInstruction(OpCodeNumber.Ldc_I4_0); writer.EmitInstructionString(OpCodeNumber.Ldstr, "param1"); writer.EmitInstruction(OpCodeNumber.Ldarg_1); writer.EmitInstructionMethod(OpCodeNumber.Newobj, _task.NameAndValueConstructor); writer.EmitInstruction(OpCodeNumber.Stelem_Ref); writer.EmitInstruction(OpCodeNumber.Ldloc_0); writer.EmitInstructionMethod(OpCodeNumber.Call, _task.MethodEntryMethod);
The code matches perfectly, so I do not understand the error. Maybe a bug in PostSharp?
|
|
|
|
|
Gael Fraiteur
SharpCrafters
|
|
This means that you have put a wrong index somewhere. The exception occurs with delay, when PostSharp compiles back the assembly, which makes it more difficult to debug.
Generally speaking, using strongly-typed instructions (for instance EmitInstructionLocalVariable(OpCodeNumber.Ldloc,variable) instead of EmitInstructionInt16(Ldloc,1), both are valid) is safer since checks happen immediately.
As I said before, PostSharp Core and MSIL are matter for a couple of weeks of learning. It's an advanced low-level API and you can't expect the same level of usability than with high-level APIes.
-gael
|
|
|
|
|
Gael Fraiteur
SharpCrafters
|
|
|
More concretely to your code: you are using Stloc_0, but did you define a variable? If yes, are you sure its index is 0?
|
|
|
|
|
Community Member
|
|
|
The IL was generated by the C# compiler based on the code I want to generate, so technically it must be correct. Just in case, this is what the C# code looks like: Log.MethodEntry("Category", "Tracing", "TracedMethod(string)", new NameAndValue[] { new NameAndValue("param1", param1) });
But with regards to your question, based on my understanding, Stloc_0 pops the reference to the created array from the stack and saves it in variable 0, Ldloc_0 then pushes the array to the stack again and Ldc_I4_0 specifies the array index of where to put the NameValue instance, which is created later on. The array index is 0 since the size of the array is only 1.
|
|
|
|
|
Gael Fraiteur
SharpCrafters
|
|
|
Sorry, I can't assist you with this. It's complex, you are going to have a difficult time, but I cannot help you every 30 minute.
|
|
|
|