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(); } }
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); }
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); }