예제 #1
0
파일: Ldftn.cs 프로젝트: sramos30/FlingOS
        /// <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
            });
        }