Example #1
0
 private EcmaCil.MethodMeta EnqueueMethod(MethodBase aMethod, object aSource, string aSourceType)
 {
     if (mLogEnabled)
     {
         LogMapPoint(aSource, aSourceType, aMethod);
     }
     if (aMethod.IsGenericMethodDefinition)
     {
         throw new Exception("Cannot queue generic method definitions");
     }
     Type xReturnType = null;
     var xMethodInfo = aMethod as MethodInfo;
     if (xMethodInfo != null)
     {
         xReturnType = xMethodInfo.ReturnType;
     }
     else
     {
         xReturnType = typeof(void);
     }
     var xQueuedMethod = new QueuedMethod(aMethod.DeclaringType, aMethod, (from item in aMethod.GetParameters()
                                                                           select item.ParameterType).ToArray(), xReturnType);
     EcmaCil.MethodMeta xMethodMeta;
     if(mMethods.TryGetValue(xQueuedMethod, out xMethodMeta)){
         return xMethodMeta;
     }
     var xDeclaringType = EnqueueType(aMethod.DeclaringType, aMethod, "Declaring type");
     xMethodMeta = new EcmaCil.MethodMeta();
     mMethodMetaToMethod.Add(xMethodMeta, aMethod);
     xMethodMeta.DeclaringType = xDeclaringType;
     xDeclaringType.Methods.Add(xMethodMeta);
     mMethods.Add(xQueuedMethod, xMethodMeta);
     mQueue.Enqueue(xQueuedMethod);
     return xMethodMeta;
 }
Example #2
0
        protected virtual void ScanMethodBody(QueuedMethod aMethod, EcmaCil.MethodMeta aMethodMeta)
        {
            if (aMethod.Method.HasBody)
            {
                var xBody     = aMethod.Method.Body;
                var xBodyMeta = aMethodMeta.Body = new EcmaCil.MethodBodyMeta();
                xBodyMeta.InitLocals = xBody.InitLocals;
                #region handle exception handling clauses
                if (xBody.HasExceptionHandlers)
                {
                    throw new Exception("ExceptionHandlers are not supported yet");
                }
                #endregion
                #region handle locals
                xBodyMeta.LocalVariables = new EcmaCil.LocalVariableMeta[xBody.Variables.Count];
                for (int i = 0; i < xBody.Variables.Count; i++)
                {
                    var xVar     = xBody.Variables[i];
                    var xVarMeta = xBodyMeta.LocalVariables[i] = new EcmaCil.LocalVariableMeta();
                    xVarMeta.LocalType = EnqueueType(xVar.VariableType, aMethod, "Local variable");
#if DEBUG
                    xVarMeta.Data[EcmaCil.DataIds.DebugMetaId] = xVar.Name + ":" + xVar.VariableType.ToString();
#endif
                }
                #endregion

                xBodyMeta.Instructions = new EcmaCil.IL.BaseInstruction[xBody.Instructions.Count];
                var xILOffsetToInstructionOffset = new Dictionary <int, int>();
                var xInstructionOffsetToILOffset = new Dictionary <int, int>();
                var xSecondStageInits            = new List <Action <EcmaCil.MethodMeta> >();
                for (int i = 0; i < xBody.Instructions.Count; i++)
                {
                    xILOffsetToInstructionOffset.Add(xBody.Instructions[i].Offset, i);
                    xInstructionOffsetToILOffset.Add(i, xBody.Instructions[i].Offset);
                }

                for (int i = 0; i < xBody.Instructions.Count; i++)
                {
                    var xInstr = xBody.Instructions[i];
                    xBodyMeta.Instructions[i] =
                        CreateInstructionMeta(aMethod, aMethodMeta, xInstr, xILOffsetToInstructionOffset, xInstructionOffsetToILOffset, i, xSecondStageInits, i + 1);
                }

                if (xSecondStageInits.Count > 0)
                {
                    foreach (var xInit in xSecondStageInits)
                    {
                        xInit(aMethodMeta);
                    }
                }
            }
        }
Example #3
0
        protected virtual void ScanMethodBody(QueuedMethod aMethod, EcmaCil.MethodMeta aMethodMeta)
        {
            var xBody = aMethod.Method.GetMethodBody();

            if (xBody != null)
            {
                var xBodyMeta = aMethodMeta.Body = new EcmaCil.MethodBodyMeta();
                xBodyMeta.InitLocals = xBody.InitLocals;
                #region handle exception handling clauses
                if (xBody.ExceptionHandlingClauses.Count > 0)
                {
                    throw new Exception("ExceptionHandlers are not supported yet");
                }
                #endregion
                #region handle locals
                xBodyMeta.LocalVariables = new EcmaCil.LocalVariableMeta[xBody.LocalVariables.Count];
                for (int i = 0; i < xBody.LocalVariables.Count; i++)
                {
                    var xVar     = xBody.LocalVariables[i];
                    var xVarMeta = xBodyMeta.LocalVariables[i] = new EcmaCil.LocalVariableMeta();
                    xVarMeta.LocalType = EnqueueType(xVar.LocalType, aMethod, "Local variable");
#if DEBUG
                    xVarMeta.Data[EcmaCil.DataIds.DebugMetaId] = xVar.LocalType.ToString();
#endif
                }
                #endregion

                //List<EcmaCil.IL.BaseInstruction> xInstructions;
                var xILOffsetToInstructionOffset = new Dictionary <int, int>();
                var xInstructionOffsetToILOffset = new Dictionary <int, int>();
                var xSecondStageInits            = new List <Action <EcmaCil.MethodMeta> >();

                var xILStream = xBody.GetILAsByteArray();
                foreach (var xPosition in ILStreamPositionReader.GetIndexes(xILStream))
                {
                    xILOffsetToInstructionOffset.Add(xPosition.Key, xPosition.Value);
                    xInstructionOffsetToILOffset.Add(xPosition.Value, xPosition.Key);
                }
                xBodyMeta.Instructions = ScanMethodBody_DoIt(aMethod.Method, aMethodMeta, xILOffsetToInstructionOffset, xInstructionOffsetToILOffset).ToArray();
            }
        }
Example #4
0
        private EcmaCil.MethodMeta EnqueueMethod(MethodBase aMethod, object aSource, string aSourceType)
        {
            if (mLogEnabled)
            {
                LogMapPoint(aSource, aSourceType, aMethod);
            }
            if (aMethod.IsGenericMethodDefinition)
            {
                throw new Exception("Cannot queue generic method definitions");
            }
            Type xReturnType = null;
            var  xMethodInfo = aMethod as MethodInfo;

            if (xMethodInfo != null)
            {
                xReturnType = xMethodInfo.ReturnType;
            }
            else
            {
                xReturnType = typeof(void);
            }
            var xQueuedMethod = new QueuedMethod(aMethod.DeclaringType, aMethod, (from item in aMethod.GetParameters()
                                                                                  select item.ParameterType).ToArray(), xReturnType);

            EcmaCil.MethodMeta xMethodMeta;
            if (mMethods.TryGetValue(xQueuedMethod, out xMethodMeta))
            {
                return(xMethodMeta);
            }
            var xDeclaringType = EnqueueType(aMethod.DeclaringType, aMethod, "Declaring type");

            xMethodMeta = new EcmaCil.MethodMeta();
            mMethodMetaToMethod.Add(xMethodMeta, aMethod);
            xMethodMeta.DeclaringType = xDeclaringType;
            xDeclaringType.Methods.Add(xMethodMeta);
            mMethods.Add(xQueuedMethod, xMethodMeta);
            mQueue.Enqueue(xQueuedMethod);
            return(xMethodMeta);
        }
Example #5
0
 protected override void ScanMethodBody(QueuedMethod aMethod, EcmaCil.MethodMeta aMethodMeta)
 {
     base.ScanMethodBody(aMethod, aMethodMeta);
 }
Example #6
0
        private BaseInstruction CreateInstructionMeta(QueuedMethod aMethod, EcmaCil.MethodMeta aMethodMeta, Instruction curInstruction, IDictionary <int, int> aILToInstructionOffset, IDictionary <int, int> aInstructionToILOffset, int aCurrentIndex, IList <Action <EcmaCil.MethodMeta> > aSecondStageInits, int aNextIndex)
        {
            switch (curInstruction.OpCode.Code)
            {
            case Code.Nop:
                return(new InstructionNone(InstructionKindEnum.Nop, aCurrentIndex));

            case Code.Pop:
                return(new InstructionNone(InstructionKindEnum.Pop, aCurrentIndex));

            case Code.Ldc_I4_S:
                return(new InstructionInt32(GetInstructionKind(curInstruction.OpCode.Code), aCurrentIndex, (int)(sbyte)curInstruction.Operand));

            case Code.Stloc_0:
                return(new InstructionInt32(InstructionKindEnum.Stloc, aCurrentIndex, 0));

            case Code.Stloc_1:
                return(new InstructionInt32(InstructionKindEnum.Stloc, aCurrentIndex, 1));

            case Code.Ldloc_0:
                return(new InstructionLocal(InstructionKindEnum.Ldloc, aCurrentIndex, aMethodMeta.Body.LocalVariables[0]));

            case Code.Ldloc_1:
                return(new InstructionLocal(InstructionKindEnum.Ldloc, aCurrentIndex, aMethodMeta.Body.LocalVariables[1]));

            case Code.Ldloc_2:
                return(new InstructionLocal(InstructionKindEnum.Ldloc, aCurrentIndex, aMethodMeta.Body.LocalVariables[2]));

            case Code.Call:
                return(new InstructionMethod(InstructionKindEnum.Call, aCurrentIndex, EnqueueMethod(curInstruction.Operand as MethodReference, aMethod.Method, "Operand value")));

            case Code.Callvirt:
                return(new InstructionMethod(InstructionKindEnum.Callvirt, aCurrentIndex, EnqueueMethod(curInstruction.Operand as MethodReference, aMethod.Method, "Operand value")));

            case Code.Stloc_2:
                return(new InstructionLocal(InstructionKindEnum.Stloc, aCurrentIndex, aMethodMeta.Body.LocalVariables[2]));

            case Code.Stloc_3:
                return(new InstructionLocal(InstructionKindEnum.Stloc, aCurrentIndex, aMethodMeta.Body.LocalVariables[3]));

            case Code.Ret:
                return(new InstructionNone(InstructionKindEnum.Ret, aCurrentIndex));

            case Code.Ldarg_0:
                return(new InstructionArgument(InstructionKindEnum.Ldarg, aCurrentIndex, aMethodMeta.Parameters[0]));

            case Code.Ldarg_1:
                return(new InstructionArgument(InstructionKindEnum.Ldarg, aCurrentIndex, aMethodMeta.Parameters[1]));

            case Code.Add:
                return(new InstructionNone(InstructionKindEnum.Add, aCurrentIndex));

            case Code.Ldstr:
                return(new InstructionString(InstructionKindEnum.Ldstr, aCurrentIndex, (string)curInstruction.Operand));

            case Code.Newobj:
                return(new InstructionMethod(InstructionKindEnum.Newobj, aCurrentIndex, EnqueueMethod(curInstruction.Operand as MethodReference, aMethod.Method, "Operand value")));

            case Code.Br_S:
            case Code.Brfalse_S:
                var xInstr        = new InstructionBranch(GetInstructionKind(curInstruction.OpCode.Code), aCurrentIndex);
                var xTargetInstr  = (Instruction)curInstruction.Operand;
                var xTargetOffset = xTargetInstr.Offset;
                aSecondStageInits.Add(delegate(EcmaCil.MethodMeta aTheMethod)
                {
                    xInstr.Target = aTheMethod.Body.Instructions[aILToInstructionOffset[xTargetOffset]];
                });
                return(xInstr);

            //    case
            //case OperandType.InlineNone:
            //    {
            //        xInstrMeta = new InstructionNone(GetInstructionKind(xInstr.OpCode.Code), i + xOffset);
            //        break;
            //    }
            //case OperandType.ShortInlineI:
            //    {
            //        xInstrMeta = new InstructionInt32(GetInstructionKind(xInstr.OpCode.Code), i + xOffset, (int)(sbyte)xInstr.Operand);
            //        break;
            //    }
            default: throw new Exception("Op '" + curInstruction.OpCode.Code + "' not implemented!");
            }
        }
Example #7
0
        private void ScanMethod(QueuedMethod aMethod, EcmaCil.MethodMeta aMethodMeta)
        {
            // todo: add support for plugs
#if DEBUG
            aMethodMeta.Data[EcmaCil.DataIds.DebugMetaId] = aMethod.Method.ToString();
#endif
            var xParamOffset = 0;
            if (!aMethod.Method.IsStatic)
            {
                xParamOffset = 1;
            }
            aMethodMeta.Parameters = new EcmaCil.MethodParameterMeta[aMethod.Method.Parameters.Count + xParamOffset];
            if (!aMethod.Method.IsStatic)
            {
                aMethodMeta.Parameters[0] = new EcmaCil.MethodParameterMeta
                {
                    IsByRef      = aMethod.Method.DeclaringType.IsValueType,
                    PropertyType = EnqueueType(aMethod.Method.DeclaringType, aMethod, "Declaring type")
                };
#if DEBUG
                aMethodMeta.Parameters[0].Data[EcmaCil.DataIds.DebugMetaId] = "$this";
#endif
            }
            for (int i = 0; i < aMethod.Method.Parameters.Count; i++)
            {
                var xParam     = aMethod.Method.Parameters[i];
                var xParamType = xParam.ParameterType;
                if (xParamType is GenericParameter)
                {
                    // todo: resolve generics.
                    throw new NotImplementedException();
                }

                var xParamMeta = aMethodMeta.Parameters[i + xParamOffset] = new EcmaCil.MethodParameterMeta();
                //if (xParamType is ReferenceType)
                //{
                //    xParamType = ((ReferenceType)xParamType).ElementType;
                //    xParamMeta.IsByRef = true;
                //}

                var xType = EnqueueType(xParamType, aMethod, "parameter");
#if DEBUG
                var xSB = new StringBuilder();
                xSB.Append(xParam.Name);
                xSB.Append(": ");
                if (xParamMeta.IsByRef)
                {
                    xSB.Append("ref ");
                }
                xSB.Append(xParamType.ToString());
                xParamMeta.Data[EcmaCil.DataIds.DebugMetaId] = xSB.ToString();
#endif
                xParamMeta.PropertyType = xType;
            }
            if (aMethod.Method.ReturnType.FullName != "System.Void")
            {
                aMethodMeta.ReturnType = EnqueueType(aMethod.Method.ReturnType, aMethod.Method, "Return Type");
            }
            aMethodMeta.IsStatic = aMethod.Method.IsStatic;
            ScanMethodBody(aMethod, aMethodMeta);
            #region Virtuals scan
            if (aMethod.Method.IsVirtual)
            {
                if (aMethod.Method.HasGenericParameters)
                {
                    throw new Exception("GEnerics not yet fully supported");
                }
                // For virtuals we need to climb up the type tree
                // and find the top base method. We then add that top
                // node to the mVirtuals list. We don't need to add the
                // types becuase adding DeclaringType will already cause
                // all ancestor types to be added.

                var           xVirtMethod = aMethod.Method;
                TypeReference xVirtType   = aMethod.Method.DeclaringType;

                xVirtMethod = xVirtMethod.GetOriginalBaseMethod();
                #region old code
                //                MethodReference xNewVirtMethod = null;
//                while (true)
//                {
//                    var xNewVirtType = xVirtType.Resolve();
//                    if (xNewVirtType.HasGenericParameters)
//                    {
//                        throw new Exception("Generics not fully supported yet!");
//                    }
//                    if (xNewVirtType == null)
//                    {
//                        xVirtType = null;
//                    }
//                    else
//                    {
//#warning // todo: verify if next code works ok with generics
//                        var xTempNewVirtMethod = xNewVirtType.  .m.Methods..GetMethod(aMethod.Method.Name, aMethod.Method.Parameters);
//                        if (xTempNewVirtMethod !=null)
//                        {
//                            if (xTempNewVirtMethod.IsVirtual)
//                            {
//                                xNewVirtMethod = xTempNewVirtMethod;
//                            }
//                        }
//                        else
//                        {
//                            xNewVirtMethod = null;
//                        }
//                    }
//                    if (xNewVirtMethod == null)
//                    {
//                        if (mVirtuals.ContainsKey(aMethod))
//                        {
//                            xVirtMethod = null;
//                        }
//                        break;
//                    }
//                    xVirtMethod = xNewVirtMethod.Resolve();
//                    xVirtType = xNewVirtType.BaseType;
//                    if (xVirtType == null)
//                    {
//                        break;
//                    }
                //                }
                #endregion old code
                if (xVirtMethod != null)
                {
                    EnqueueMethod(xVirtMethod, aMethod, "Virtual Base");

                    foreach (var xType in mTypes)
                    {
                        if (xType.Key.Type.IsSubclassOf(xVirtMethod.DeclaringType))
                        {
                            //xType.Key.Type.res
                            //var xNewMethod = xType.Key.Type.Methods.GetMethod(aMethod.Method.Name, aMethod.Method.Parameters);
                            //if (xNewMethod != null)
                            //{
                            //                        // We need to check IsVirtual, a non virtual could
                            //                        // "replace" a virtual above it?
                            //    // MtW: correct
                            //    if (xNewMethod.IsVirtual)
                            //    {
                            //        EnqueueMethod(xNewMethod, aMethod, "Virtual Downscan");
                            //    }
                            //}
                            throw new NotImplementedException();
                        }
                    }
                }
            }
            #endregion
        }
Example #8
0
        private EcmaCil.MethodMeta EnqueueMethod(MethodReference aMethod, object aSource, string aSourceType)
        {
            if (mLogEnabled)
            {
                LogMapPoint(aSource, aSourceType, aMethod);
            }
            List <TypeReference> xTypeArgs = null;
            var              xGenSpec      = aMethod as GenericInstanceMethod;
            TypeDefinition   xTypeDef;
            MethodDefinition xMethodDef;
            TypeReference    xRefType;

            if (xGenSpec != null)
            {
                xMethodDef = ResolveMethod(xGenSpec.ElementMethod);
                xRefType   = xGenSpec.DeclaringType;
                xTypeArgs  = new List <TypeReference>();
                foreach (TypeReference xArg in xGenSpec.GenericArguments)
                {
                    xTypeArgs.Add(xArg);
                }
            }
            else
            {
                xMethodDef = ResolveMethod(aMethod);
                xRefType   = aMethod.DeclaringType;
            }
            #region resolve type
            xTypeDef = xRefType as TypeDefinition;
            if (xTypeDef == null)
            {
                var xGenType = xRefType as GenericInstanceType;
                if (xGenType != null)
                {
                    xTypeDef = ResolveType(xGenType.DeclaringType);
                    if (xTypeArgs == null)
                    {
                        xTypeArgs = new List <TypeReference>();
                    }
                    for (int i = 0; i < xGenType.GenericArguments.Count; i++)
                    {
                        xTypeArgs.Insert(i, xGenType.GenericArguments[i]);
                    }
                }
                else
                {
                    xTypeDef = ResolveType(xRefType);
                }
            }
            #endregion
            var xQueuedMethod = new QueuedMethod(xTypeDef, xMethodDef, (xTypeArgs == null ? null : xTypeArgs.ToArray()));
            EcmaCil.MethodMeta xMethodMeta;
            if (mMethods.TryGetValue(xQueuedMethod, out xMethodMeta))
            {
                return(xMethodMeta);
            }
            var xDeclaringType = EnqueueType(xRefType, aMethod, "Declaring type");
            xMethodMeta = new EcmaCil.MethodMeta();
            xMethodMeta.DeclaringType = xDeclaringType;
            xDeclaringType.Methods.Add(xMethodMeta);
            mMethods.Add(xQueuedMethod, xMethodMeta);
            mQueue.Enqueue(xQueuedMethod);
            return(xMethodMeta);
        }
Example #9
0
        private void ScanMethod(QueuedMethod aMethod, EcmaCil.MethodMeta aMethodMeta)
        {
            // todo: add support for plugs
#if DEBUG
            aMethodMeta.Data[EcmaCil.DataIds.DebugMetaId] = aMethod.Method.GetFullName();
#endif
            aMethodMeta.IsVirtual = aMethod.Method.IsVirtual;
            aMethodMeta.IsPublic  = aMethod.Method.IsPublic;
            var xMethod = aMethod.Method;
            aMethodMeta.StartsNewVirtualTree = aMethodMeta.IsVirtual && ((aMethod.Method.Attributes & MethodAttributes.NewSlot) == MethodAttributes.NewSlot);

            var xParamOffset = 0;
            if (!aMethod.Method.IsStatic)
            {
                xParamOffset = 1;
            }
            var xMethodParameters = aMethod.Method.GetParameters();
            aMethodMeta.Parameters = new EcmaCil.MethodParameterMeta[xMethodParameters.Length + xParamOffset];
            if (!aMethod.Method.IsStatic)
            {
                aMethodMeta.Parameters[0] = new EcmaCil.MethodParameterMeta
                {
                    IsByRef      = aMethod.Method.DeclaringType.IsValueType,
                    PropertyType = EnqueueType(aMethod.Method.DeclaringType, aMethod, "Declaring type")
                };
#if DEBUG
                aMethodMeta.Parameters[0].Data[EcmaCil.DataIds.DebugMetaId] = "$this";
#endif
            }
            for (int i = 0; i < xMethodParameters.Length; i++)
            {
                var xParam     = xMethodParameters[i];
                var xParamType = xParam.ParameterType;
                var xParamMeta = aMethodMeta.Parameters[i + xParamOffset] = new EcmaCil.MethodParameterMeta();
                var xType      = EnqueueType(xParamType, aMethod, "parameter");
#if DEBUG
                var xSB = new StringBuilder();
                xSB.Append(xParam.Name);
                xSB.Append(": ");
                if (xParamMeta.IsByRef)
                {
                    xSB.Append("ref ");
                }
                xSB.Append(xParamType.ToString());
                xParamMeta.Data[EcmaCil.DataIds.DebugMetaId] = xSB.ToString();
#endif
                xParamMeta.PropertyType = xType;
            }

            if (aMethodMeta.IsVirtual && ((aMethod.Method.Attributes & MethodAttributes.NewSlot) != MethodAttributes.NewSlot))
            {
                // method is override
                // now need to find parent method, just one level up, because when the parent method is scanned, its parent method will be found..
                var xBaseType = aMethod.Method.DeclaringType;
#if DEBUG
                if (xBaseType == null)
                {
                    throw new Exception("New virtual method found, but declaring type has no base type");
                }
#endif
                var xBindFlags = BindingFlags.Instance;
                if (xMethod.IsPublic)
                {
                    xBindFlags |= BindingFlags.Public;
                }
                else
                {
                    xBindFlags |= BindingFlags.NonPublic;
                }
                var xFoundMethod = xBaseType.GetMethod(aMethod.Method.Name,
                                                       xBindFlags, null, (from item in xMethodParameters
                                                                          select item.ParameterType).ToArray(), null);
                if (xFoundMethod != null)
                {
                    EnqueueMethod(xFoundMethod, aMethod, "Overridden method");
                }
            }

            var xMethodInfo = aMethod.Method as MethodInfo;
            var xReturnType = typeof(void);
            if (xMethodInfo != null)
            {
                xReturnType = xMethodInfo.ReturnType;
            }

            if (xReturnType != typeof(void))
            {
                aMethodMeta.ReturnType = EnqueueType(xReturnType, aMethod.Method, "Return Type");
            }
            aMethodMeta.IsStatic = aMethod.Method.IsStatic;
            ScanMethodBody(aMethod, aMethodMeta);
        }
Example #10
0
        protected List <EcmaCil.IL.BaseInstruction> ScanMethodBody_DoIt(MethodBase aMethod, EcmaCil.MethodMeta aMethodMeta, IDictionary <int, int> aILOffsetToInstructionIndex, IDictionary <int, int> aInstructionIndexToILOffset)
        {
            var xResult = new List <EcmaCil.IL.BaseInstruction>(aILOffsetToInstructionIndex.Count);
            var xBody   = aMethod.GetMethodBody();

            // Cache for use in field and method resolution
            Type[] xTypeGenArgs   = null;
            Type[] xMethodGenArgs = null;
            if (aMethod.DeclaringType.IsGenericType)
            {
                xTypeGenArgs = aMethod.DeclaringType.GetGenericArguments();
            }
            if (aMethod.IsGenericMethod)
            {
                xMethodGenArgs = aMethod.GetGenericArguments();
            }

            // Some methods return no body. Not sure why.. have to investigate
            // They arent abstracts or icalls...
            // MtW: how about externs (pinvoke, etc)
            if (xBody == null)
            {
                return(null);
            }

            var xIL  = xBody.GetILAsByteArray();
            int xPos = 0;
            var xInstructionIndex = 0;
            var xInitSecondStage  = new List <Action>(aILOffsetToInstructionIndex.Count);

            while (xPos < xIL.Length)
            {
                ExceptionHandlingClause xCurrentHandler = null;
                #region Determine current handler
                // todo: add support for nested handlers using a stack or so..
                foreach (ExceptionHandlingClause xHandler in xBody.ExceptionHandlingClauses)
                {
                    if (xHandler.TryOffset > 0)
                    {
                        if (xHandler.TryOffset <= xPos && (xHandler.TryLength + xHandler.TryOffset + 1) > xPos) // + 1 because index should be less than the try
                        {
                            if (xCurrentHandler == null)
                            {
                                xCurrentHandler = xHandler;
                                continue;
                            }
                            else if (xHandler.TryOffset > xCurrentHandler.TryOffset && (xHandler.TryLength + xHandler.TryOffset) < (xCurrentHandler.TryLength + xCurrentHandler.TryOffset))
                            {
                                // only replace if the current found handler is narrower
                                xCurrentHandler = xHandler;
                                continue;
                            }
                        }
                    }
                    if (xHandler.HandlerOffset > 0)
                    {
                        if (xHandler.HandlerOffset <= xPos && (xHandler.HandlerOffset + xHandler.HandlerLength + 1) > xPos)
                        {
                            if (xCurrentHandler == null)
                            {
                                xCurrentHandler = xHandler;
                                continue;
                            }
                            else if (xHandler.HandlerOffset > xCurrentHandler.HandlerOffset && (xHandler.HandlerOffset + xHandler.HandlerLength) < (xCurrentHandler.HandlerOffset + xCurrentHandler.HandlerLength))
                            {
                                // only replace if the current found handler is narrower
                                xCurrentHandler = xHandler;
                                continue;
                            }
                        }
                    }
                    if ((xHandler.Flags & ExceptionHandlingClauseOptions.Filter) > 0)
                    {
                        if (xHandler.FilterOffset > 0)
                        {
                            if (xHandler.FilterOffset <= xPos)
                            {
                                if (xCurrentHandler == null)
                                {
                                    xCurrentHandler = xHandler;
                                    continue;
                                }
                                else if (xHandler.FilterOffset > xCurrentHandler.FilterOffset)
                                {
                                    // only replace if the current found handler is narrower
                                    xCurrentHandler = xHandler;
                                    continue;
                                }
                            }
                        }
                    }
                }
                #endregion
                OpCodeEnum xOpCodeVal;
                OpCode     xOpCode;
                int        xOpPos = xPos;
                if (xIL[xPos] == 0xFE)
                {
                    xOpCodeVal = (OpCodeEnum)(0xFE00 | xIL[xPos + 1]);
                    xOpCode    = mOpCodesHi[xIL[xPos + 1]];
                    xPos       = xPos + 2;
                }
                else
                {
                    xOpCodeVal = (OpCodeEnum)xIL[xPos];
                    xOpCode    = mOpCodesLo[xIL[xPos]];
                    xPos++;
                }

                EcmaCil.IL.BaseInstruction xILOpCode = null;
                Cil.InstructionBranch      xBranch;
                Console.WriteLine(xOpCode.ToString() + " " + xOpCode.OperandType);
                #region switch(xOpCode.OperandType)
                switch (xOpCode.OperandType)
                {
                // No operand.
                case OperandType.InlineNone:
                {
                    #region Inline none options
                    // These shortcut translation regions expand shortcut ops into full ops
                    // This elminates the amount of code required in the assemblers
                    // by allowing them to ignore the shortcuts
                    switch (xOpCodeVal)
                    {
                    case OpCodeEnum.Ldarg_0:
                        xILOpCode = new Cil.InstructionArgument(EcmaCil.IL.InstructionKindEnum.Ldarg, xInstructionIndex, aMethodMeta.Parameters[0]);
                        break;

                    case OpCodeEnum.Ldarg_1:
                        xILOpCode = new Cil.InstructionArgument(EcmaCil.IL.InstructionKindEnum.Ldarg, xInstructionIndex, aMethodMeta.Parameters[1]);
                        break;

                    case OpCodeEnum.Ldarg_2:
                        xILOpCode = new Cil.InstructionArgument(EcmaCil.IL.InstructionKindEnum.Ldarg, xInstructionIndex, aMethodMeta.Parameters[2]);
                        break;

                    case OpCodeEnum.Ldarg_3:
                        xILOpCode = new Cil.InstructionArgument(EcmaCil.IL.InstructionKindEnum.Ldarg, xInstructionIndex, aMethodMeta.Parameters[3]);
                        break;

                    case OpCodeEnum.Ldc_I4_0:
                        xILOpCode = new Cil.InstructionInt32(EcmaCil.IL.InstructionKindEnum.Ldc_I4, xInstructionIndex, 0);
                        break;

                    case OpCodeEnum.Ldc_I4_1:
                        xILOpCode = new Cil.InstructionInt32(EcmaCil.IL.InstructionKindEnum.Ldc_I4, xInstructionIndex, 1);
                        break;

                    case OpCodeEnum.Ldc_I4_2:
                        xILOpCode = new Cil.InstructionInt32(EcmaCil.IL.InstructionKindEnum.Ldc_I4, xInstructionIndex, 2);
                        break;

                    case OpCodeEnum.Ldc_I4_3:
                        xILOpCode = new Cil.InstructionInt32(EcmaCil.IL.InstructionKindEnum.Ldc_I4, xInstructionIndex, 3);
                        break;

                    case OpCodeEnum.Ldc_I4_4:
                        xILOpCode = new Cil.InstructionInt32(EcmaCil.IL.InstructionKindEnum.Ldc_I4, xInstructionIndex, 4);
                        break;

                    case OpCodeEnum.Ldc_I4_5:
                        xILOpCode = new Cil.InstructionInt32(EcmaCil.IL.InstructionKindEnum.Ldc_I4, xInstructionIndex, 5);
                        break;

                    case OpCodeEnum.Ldc_I4_6:
                        xILOpCode = new Cil.InstructionInt32(EcmaCil.IL.InstructionKindEnum.Ldc_I4, xInstructionIndex, 6);
                        break;

                    case OpCodeEnum.Ldc_I4_7:
                        xILOpCode = new Cil.InstructionInt32(EcmaCil.IL.InstructionKindEnum.Ldc_I4, xInstructionIndex, 7);
                        break;

                    case OpCodeEnum.Ldc_I4_8:
                        xILOpCode = new Cil.InstructionInt32(EcmaCil.IL.InstructionKindEnum.Ldc_I4, xInstructionIndex, 8);
                        break;

                    case OpCodeEnum.Ldc_I4_M1:
                        xILOpCode = new Cil.InstructionInt32(EcmaCil.IL.InstructionKindEnum.Ldc_I4, xInstructionIndex, -1);
                        break;

                    case OpCodeEnum.Ldloc_0:
                        xILOpCode = new Cil.InstructionLocal(EcmaCil.IL.InstructionKindEnum.Ldloc, xInstructionIndex, aMethodMeta.Body.LocalVariables[0]);
                        break;

                    case OpCodeEnum.Ldloc_1:
                        xILOpCode = new Cil.InstructionLocal(EcmaCil.IL.InstructionKindEnum.Ldloc, xInstructionIndex, aMethodMeta.Body.LocalVariables[1]);
                        break;

                    case OpCodeEnum.Ldloc_2:
                        xILOpCode = new Cil.InstructionLocal(EcmaCil.IL.InstructionKindEnum.Ldloc, xInstructionIndex, aMethodMeta.Body.LocalVariables[2]);
                        break;

                    case OpCodeEnum.Ldloc_3:
                        xILOpCode = new Cil.InstructionLocal(EcmaCil.IL.InstructionKindEnum.Ldloc, xInstructionIndex, aMethodMeta.Body.LocalVariables[3]);
                        break;

                    case OpCodeEnum.Stloc_0:
                        xILOpCode = new Cil.InstructionLocal(EcmaCil.IL.InstructionKindEnum.Stloc, xInstructionIndex, aMethodMeta.Body.LocalVariables[0]);
                        break;

                    case OpCodeEnum.Stloc_1:
                        xILOpCode = new Cil.InstructionLocal(EcmaCil.IL.InstructionKindEnum.Stloc, xInstructionIndex, aMethodMeta.Body.LocalVariables[1]);
                        break;

                    case OpCodeEnum.Stloc_2:
                        xILOpCode = new Cil.InstructionLocal(EcmaCil.IL.InstructionKindEnum.Stloc, xInstructionIndex, aMethodMeta.Body.LocalVariables[2]);
                        break;

                    case OpCodeEnum.Stloc_3:
                        xILOpCode = new Cil.InstructionLocal(EcmaCil.IL.InstructionKindEnum.Stloc, xInstructionIndex, aMethodMeta.Body.LocalVariables[3]);
                        break;

                    default:
                        xILOpCode = new Cil.InstructionNone((EcmaCil.IL.InstructionKindEnum)xOpCodeVal, xInstructionIndex);
                        break;
                    }
                    #endregion
                    break;
                }

                case OperandType.ShortInlineBrTarget:
                {
                    #region Inline branch
                    // By calculating target, we assume all branches are within a method
                    // So far at least wtih csc, its true. We check it with CheckBranch
                    // just in case.
                    int xTarget = xPos + 1 + (sbyte)xIL[xPos];
                    CheckBranch(xTarget, xIL.Length);
                    switch (xOpCodeVal)
                    {
                    case OpCodeEnum.Beq_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Beq, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    case OpCodeEnum.Bge_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Bge, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    case OpCodeEnum.Bge_Un_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Bge_Un, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    case OpCodeEnum.Bgt_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Bgt, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    case OpCodeEnum.Bgt_Un_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Bgt_Un, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    case OpCodeEnum.Ble_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Ble, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    case OpCodeEnum.Ble_Un_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Ble_Un, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    case OpCodeEnum.Blt_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Blt, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    case OpCodeEnum.Blt_Un_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Blt_Un, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    case OpCodeEnum.Bne_Un_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Bne_Un, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    case OpCodeEnum.Br_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Br, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    case OpCodeEnum.Brfalse_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Brfalse, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    case OpCodeEnum.Brtrue_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Brtrue, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    case OpCodeEnum.Leave_S:
                        xBranch   = new Cil.InstructionBranch(EcmaCil.IL.InstructionKindEnum.Leave, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;

                    default:
                        xBranch   = new Cil.InstructionBranch((EcmaCil.IL.InstructionKindEnum)xOpCodeVal, xInstructionIndex);
                        xILOpCode = xBranch;
                        xInitSecondStage.Add(delegate
                            {
                                xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                            });
                        break;
                    }
                    xPos = xPos + 1;
                    break;
                    #endregion
                }

                case OperandType.InlineBrTarget:
                {
                    int xTarget = xPos + 4 + (Int32)ReadInt32(xIL, xPos);
                    CheckBranch(xTarget, xIL.Length);
                    xILOpCode = xBranch = new Cil.InstructionBranch((EcmaCil.IL.InstructionKindEnum)xOpCodeVal, xInstructionIndex);
                    xInitSecondStage.Add(delegate
                        {
                            xBranch.Target = xResult[aILOffsetToInstructionIndex[xTarget]];
                        });
                    xPos = xPos + 4;
                    break;
                }

                case OperandType.ShortInlineI:
                    switch (xOpCodeVal)
                    {
                    case OpCodeEnum.Ldc_I4_S:
                        xILOpCode = new Cil.InstructionInt32(EcmaCil.IL.InstructionKindEnum.Ldc_I4, xInstructionIndex, xIL[xPos]);
                        break;

                    default:
                        xILOpCode = new Cil.InstructionInt32((EcmaCil.IL.InstructionKindEnum)xOpCodeVal, xInstructionIndex, xIL[xPos]);
                        break;
                    }
                    xPos = xPos + 1;
                    break;

                case OperandType.InlineI:
                    xILOpCode = new Cil.InstructionInt32((Cil.InstructionKindEnum)xOpCodeVal, xInstructionIndex, ReadInt32(xIL, xPos));
                    xPos      = xPos + 4;
                    break;

                case OperandType.InlineI8:
                    xILOpCode = new Cil.InstructionInt64((Cil.InstructionKindEnum)xOpCodeVal, xInstructionIndex, ReadInt64(xIL, xPos));
                    xPos      = xPos + 8;
                    break;

                case OperandType.ShortInlineR:
                    // this is not correct:
                    //xILOpCode = new Cil.InstructionSingle(
                    //xILOpCode = new ILOpCodes.OpSingle(xOpCodeVal, xOpPos, xPos + 4, BitConverter.ToSingle(xIL, xPos), xCurrentHandler);
                    //xPos = xPos + 4;
                    //break;
                    throw new NotImplementedException();

                case OperandType.InlineR:
                    // this is not correct
                    //xILOpCode = new ILOpCodes.OpDouble(xOpCodeVal, xOpPos, xPos + 8, BitConverter.ToDouble(xIL, xPos), xCurrentHandler);
                    //xPos = xPos + 8;
                    //break;
                    throw new NotImplementedException();

                // The operand is a 32-bit metadata token.
                case OperandType.InlineField:
                    throw new NotImplementedException();
                //{
                //    var xValue = aMethod.Module.ResolveField((int)ReadInt32(xIL, xPos), xTypeGenArgs, xMethodGenArgs);

                //    xILOpCode = new ILOpCodes.OpField(xOpCodeVal, xOpPos, xPos + 4, xValue, xCurrentHandler);
                //    xPos = xPos + 4;
                //    break;
                //}

                // The operand is a 32-bit metadata token.
                case OperandType.InlineMethod:
                    var xTargetMethod = EnqueueMethod(aMethod.DeclaringType.Module.ResolveMethod(ReadInt32(xIL, xPos)), aMethod, "Method Call");
                    xILOpCode = new Cil.InstructionMethod((Cil.InstructionKindEnum)xOpCodeVal, xInstructionIndex, xTargetMethod);
                    xPos      = xPos + 4;
                    break;
                //{
                //    var xValue = aMethod.Module.ResolveMethod((int)ReadInt32(xIL, xPos), xTypeGenArgs, xMethodGenArgs);
                //    xILOpCode = new ILOpCodes.OpMethod(xOpCodeVal, xOpPos, xPos + 4, xValue, xCurrentHandler);
                //    xPos = xPos + 4;
                //    break;
                //}

                // 32-bit metadata signature token.
                case OperandType.InlineSig:
                    throw new NotImplementedException();

                case OperandType.InlineString:
                    xILOpCode = new Cil.InstructionString(Cil.InstructionKindEnum.Ldstr, xInstructionIndex, aMethod.Module.ResolveString(ReadInt32(xIL, xPos)));
                    xPos      = xPos + 4;
                    break;

                case OperandType.InlineSwitch:
                    throw new NotImplementedException();
                //{
                //    int xCount = (int)ReadInt32(xIL, xPos);
                //    xPos = xPos + 4;
                //    int xNextOpPos = xPos + xCount * 4;
                //    int[] xBranchLocations = new int[xCount];
                //    for (int i = 0; i < xCount; i++)
                //    {
                //        xBranchLocations[i] = xNextOpPos + (int)ReadInt32(xIL, xPos + i * 4);
                //        CheckBranch(xBranchLocations[i], xIL.Length);
                //    }
                //    xILOpCode = new ILOpCodes.OpSwitch(xOpCodeVal, xOpPos, xPos, xBranchLocations, xCurrentHandler);
                //    xPos = xNextOpPos;
                //    break;
                //}

                // The operand is a FieldRef, MethodRef, or TypeRef token.
                case OperandType.InlineTok:
                    throw new NotImplementedException();
                //xILOpCode = new ILOpCodes.OpToken(xOpCodeVal, xOpPos, xPos + 4, ReadInt32(xIL, xPos), aMethod.Module, xTypeGenArgs, xMethodGenArgs, xCurrentHandler);
                //                        xPos = xPos + 4;
                //                        break;

                // 32-bit metadata token.
                case OperandType.InlineType:
                    throw new NotImplementedException();
                //{
                //    var xValue = aMethod.Module.ResolveType((int)ReadInt32(xIL, xPos), xTypeGenArgs, xMethodGenArgs);
                //    xILOpCode = new ILOpCodes.OpType(xOpCodeVal, xOpPos, xPos + 4, xValue, xCurrentHandler);
                //    xPos = xPos + 4;
                //    break;
                //}

                case OperandType.ShortInlineVar:
                    switch (xOpCodeVal)
                    {
                    case OpCodeEnum.Ldloc_S:
                        xILOpCode = new Cil.InstructionLocal(Cil.InstructionKindEnum.Ldloc, xInstructionIndex, aMethodMeta.Body.LocalVariables[xIL[xPos]]);
                        break;

                    case OpCodeEnum.Ldloca_S:
                        xILOpCode = new Cil.InstructionLocal(Cil.InstructionKindEnum.Ldloca, xInstructionIndex, aMethodMeta.Body.LocalVariables[xIL[xPos]]);
                        break;

                    case OpCodeEnum.Ldarg_S:
                        xILOpCode = new Cil.InstructionArgument(Cil.InstructionKindEnum.Ldarg, xInstructionIndex, aMethodMeta.Parameters[xIL[xPos]]);
                        break;

                    case OpCodeEnum.Ldarga_S:
                        xILOpCode = new Cil.InstructionArgument(Cil.InstructionKindEnum.Ldarga, xInstructionIndex, aMethodMeta.Parameters[xIL[xPos]]);
                        break;

                    case OpCodeEnum.Starg_S:
                        xILOpCode = new Cil.InstructionArgument(Cil.InstructionKindEnum.Starg, xInstructionIndex, aMethodMeta.Parameters[xIL[xPos]]);
                        break;

                    case OpCodeEnum.Stloc_S:
                        xILOpCode = new Cil.InstructionLocal(Cil.InstructionKindEnum.Stloc, xInstructionIndex, aMethodMeta.Body.LocalVariables[xIL[xPos]]);
                        break;

                    default:
                        throw new NotImplementedException();
                        //xILOpCode = new ILOpCodes.OpVar(xOpCodeVal, xOpPos, xPos + 1, xIL[xPos], xCurrentHandler);
                        //break;
                    }
                    xPos = xPos + 1;
                    break;

                case OperandType.InlineVar:
                    //xILOpCode = new ILOpCodes.OpVar(xOpCodeVal, xOpPos, xPos + 2, ReadUInt16(xIL, xPos), xCurrentHandler);
                    //xPos = xPos + 2;
                    throw new NotImplementedException();
                    break;

                default:
                    throw new Exception("Unknown OperandType");
                }
                #endregion switch(xOpCode.OperandType)
                xResult.Add(xILOpCode);
                xInstructionIndex++;
            }
            foreach (var xAction in xInitSecondStage)
            {
                xAction();
            }
            return(xResult);
        }
Example #11
0
 private EcmaCil.MethodMeta EnqueueMethod(MethodReference aMethod, object aSource, string aSourceType)
 {
     if (mLogEnabled)
     {
         LogMapPoint(aSource, aSourceType, aMethod);
     }
     List<TypeReference> xTypeArgs = null;
     var xGenSpec = aMethod as GenericInstanceMethod;
     TypeDefinition xTypeDef;
     MethodDefinition xMethodDef;
     TypeReference xRefType;
     if (xGenSpec != null)
     {
         xMethodDef = ResolveMethod(xGenSpec.ElementMethod);
         xRefType = xGenSpec.DeclaringType;
         xTypeArgs = new List<TypeReference>();
         foreach (TypeReference xArg in xGenSpec.GenericArguments)
         {
             xTypeArgs.Add(xArg);
         }
     }
     else
     {
         xMethodDef = ResolveMethod(aMethod);
         xRefType = aMethod.DeclaringType;
     }
     #region resolve type
     xTypeDef = xRefType as TypeDefinition;
     if (xTypeDef == null)
     {
         var xGenType = xRefType as GenericInstanceType;
         if (xGenType != null)
         {
             xTypeDef = ResolveType(xGenType.DeclaringType);
             if (xTypeArgs == null)
             {
                 xTypeArgs = new List<TypeReference>();
             }
             for (int i = 0; i < xGenType.GenericArguments.Count; i++)
             {
                 xTypeArgs.Insert(i, xGenType.GenericArguments[i]);
             }
         }
         else
         {
             xTypeDef = ResolveType(xRefType);
         }
     }
     #endregion
     var xQueuedMethod = new QueuedMethod(xTypeDef, xMethodDef, (xTypeArgs == null ? null : xTypeArgs.ToArray()));
     EcmaCil.MethodMeta xMethodMeta;
     if(mMethods.TryGetValue(xQueuedMethod, out xMethodMeta)){
         return xMethodMeta;
     }
     var xDeclaringType = EnqueueType(xRefType, aMethod, "Declaring type");
     xMethodMeta = new EcmaCil.MethodMeta();
     xMethodMeta.DeclaringType = xDeclaringType;
     xDeclaringType.Methods.Add(xMethodMeta);
     mMethods.Add(xQueuedMethod, xMethodMeta);
     mQueue.Enqueue(xQueuedMethod);
     return xMethodMeta;
 }