示例#1
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();
            }
        }
示例#2
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);
        }
示例#3
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);
        }