/// <summary> /// See base class documentation. /// </summary> /// <param name="theOp">See base class documentation.</param> /// <param name="conversionState">See base class documentation.</param> /// <returns>See base class documentation.</returns> public override void Convert(ILConversionState conversionState, ILOp theOp) { //Get the ID (i.e. ASM label) of the method to load a pointer to Types.MethodInfo methodInfo = conversionState.TheILLibrary.GetMethodInfo(theOp.MethodToCall); string methodID = methodInfo.ID; bool addExternalLabel = methodID != conversionState.Input.TheMethodInfo.ID; //If we want to load the pointer at a specified IL op number: if (theOp.LoadAtILOpAfterOp != null) { ILBlock anILBlock = conversionState.TheILLibrary.GetILBlock(methodInfo); int index = anILBlock.ILOps.IndexOf(theOp.LoadAtILOpAfterOp); if (index == -1) { throw new NullReferenceException("LoadAtILOpAfterOp not found in IL block!"); } index++; methodID = ASM.ASMBlock.GenerateLabel(methodID, anILBlock.PositionOf(anILBlock.ILOps[index])); } else if (theOp.LoadAtILOffset != int.MaxValue) { //Append the IL sub-label to the ID ILBlock anILBlock = conversionState.TheILLibrary.GetILBlock(methodInfo); methodID = ASM.ASMBlock.GenerateLabel(methodID, anILBlock.PositionOf(anILBlock.At(theOp.LoadAtILOffset))); //Note: This is used by try/catch/finally blocks for pushing pointers // to catch/finally handlers and filters } if (addExternalLabel) { conversionState.AddExternalLabel(methodID); } //Push the pointer to the function conversionState.Append(new ASMOps.La() { Dest = "$t4", Label = methodID }); conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t4" }); conversionState.CurrentStackFrame.Stack.Push(new StackItem() { isFloat = false, sizeOnStackInBytes = 4, isGCManaged = false }); }