public static uint GetStackCountForLocal(_MethodInfo aMethod, Type aField) { var xSize = SizeOfType(aField); var xResult = xSize / 4; if (xSize % 4 != 0) { xResult++; } return(xResult); }
public static uint GetEBPOffsetForLocal(_MethodInfo aMethod, int localIndex) { var xLocalInfos = aMethod.MethodBase.GetLocalVariables(); uint xOffset = 4; for (int i = 0; i < xLocalInfos.Count; i++) { if (i == localIndex) { break; } var xField = xLocalInfos[i]; xOffset += GetStackCountForLocal(aMethod, xField.Type) * 4; } return(xOffset); }
public _MethodInfo(MethodBase aMethodBase, UInt32 aUID, TypeEnum aType, _MethodInfo aPlugMethod, bool isInlineAssembler) { MethodBase = aMethodBase; UID = aUID; Type = aType; PlugMethod = aPlugMethod; IsInlineAssembler = isInlineAssembler; var attribs = aMethodBase.GetCustomAttributes <DebugStub>(false).ToList(); if (attribs.Any()) { DebugStub attrib = new DebugStub { Off = attribs[0].Off, }; DebugStubOff = attrib.Off; } }
public _MethodInfo(MethodBase aMethodBase, UInt32 aUID, TypeEnum aType, _MethodInfo aPlugMethod, Type aMethodAssembler) : this(aMethodBase, aUID, aType, aPlugMethod, false) { MethodAssembler = aMethodAssembler; }
protected static void Jump_End(_MethodInfo aMethod) { XS.Jump(GetLabel(aMethod) + AppAssembler.EndOfMethodLabelNameNormal); }
protected static void Jump_Exception(_MethodInfo aMethod) { // todo: port to numeric labels XS.Jump(GetLabel(aMethod) + AppAssembler.EndOfMethodLabelNameException); }
public static string GetLabel(_MethodInfo aMethod, int aPos) { return(LabelName.Get(GetLabel(aMethod), aPos)); }
public static string GetLabel(_MethodInfo aMethod, ILOpCode aOpCode) { return(GetLabel(aMethod, aOpCode.Position)); }
public static void EmitExceptionLogic(Assembler.Assembler aAssembler, _MethodInfo aMethodInfo, ILOpCode aCurrentOpCode, bool aDoTest, Action aCleanup, string aJumpTargetNoException = null) { if (aJumpTargetNoException == null) { aJumpTargetNoException = GetLabel(aMethodInfo, aCurrentOpCode.NextPosition); } string xJumpTo = null; if (aCurrentOpCode != null && aCurrentOpCode.CurrentExceptionRegion != null) { // todo add support for nested handlers, see comment in Engine.cs //if (!((aMethodInfo.CurrentHandler.HandlerOffset < aCurrentOpOffset) || (aMethodInfo.CurrentHandler.HandlerLength + aMethodInfo.CurrentHandler.HandlerOffset) <= aCurrentOpOffset)) { XS.Comment(String.Format("CurrentOffset = {0}, HandlerStartOffset = {1}", aCurrentOpCode.Position, aCurrentOpCode.CurrentExceptionRegion.HandlerOffset)); if (aCurrentOpCode.CurrentExceptionRegion.HandlerOffset > aCurrentOpCode.Position) { switch (aCurrentOpCode.CurrentExceptionRegion.Kind) { case ExceptionRegionKind.Catch: { xJumpTo = GetLabel(aMethodInfo, aCurrentOpCode.CurrentExceptionRegion.HandlerOffset); break; } case ExceptionRegionKind.Finally: { xJumpTo = GetLabel(aMethodInfo, aCurrentOpCode.CurrentExceptionRegion.HandlerOffset); break; } default: { throw new Exception("ExceptionHandlerType '" + aCurrentOpCode.CurrentExceptionRegion.Kind.ToString() + "' not supported yet!"); } } } } // if aDoTest is true, we check ECX for exception flags if (!aDoTest) { //new CPU.Call("_CODE_REQUESTED_BREAK_"); if (xJumpTo == null) { Jump_Exception(aMethodInfo); } else { XS.Jump(xJumpTo); } } else { XS.Test(XSRegisters.ECX, 2); if (aCleanup != null) { XS.Jump(CPU.ConditionalTestEnum.Equal, aJumpTargetNoException); aCleanup(); if (xJumpTo == null) { XS.Jump(CPU.ConditionalTestEnum.NotEqual, GetLabel(aMethodInfo) + AppAssembler.EndOfMethodLabelNameException); } else { XS.Jump(CPU.ConditionalTestEnum.NotEqual, xJumpTo); } } else { if (xJumpTo == null) { XS.Jump(CPU.ConditionalTestEnum.NotEqual, GetLabel(aMethodInfo) + AppAssembler.EndOfMethodLabelNameException); } else { XS.Jump(CPU.ConditionalTestEnum.NotEqual, xJumpTo); } } } }
// This is called execute and not assemble, as the scanner // could be used for other things, profiling, analysis, reporting, etc public abstract void Execute(_MethodInfo aMethod, ILOpCode aOpCode);
protected void Assemble() { foreach (var xItem in mItems) { if (xItem is MethodBase xMethod) { var xParams = xMethod.GetParameters(); var xParamTypes = xParams.Select(q => q.ParameterType).ToArray(); var xPlug = mPlugManager.ResolvePlug(xMethod, xParamTypes); var xMethodType = _MethodInfo.TypeEnum.Normal; Type xPlugAssembler = null; _MethodInfo xPlugInfo = null; var xMethodInline = xMethod.GetCustomAttribute <InlineAttribute>(); if (xMethodInline != null) { // inline assembler, shouldn't come here.. continue; } var xMethodIdMethod = mItemsList.IndexOf(xMethod); if (xMethodIdMethod == -1) { throw new Exception("Method not in scanner list!"); } PlugMethod xPlugAttrib = null; if (xPlug != null) { xMethodType = _MethodInfo.TypeEnum.NeedsPlug; xPlugAttrib = xPlug.GetCustomAttribute <PlugMethod>(); var xInlineAttrib = xPlug.GetCustomAttribute <InlineAttribute>(); var xMethodIdPlug = mItemsList.IndexOf(xPlug); if ((xMethodIdPlug == -1) && (xInlineAttrib == null)) { throw new Exception("Plug method not in scanner list!"); } if ((xPlugAttrib != null) && (xInlineAttrib == null)) { xPlugAssembler = xPlugAttrib.Assembler; xPlugInfo = new _MethodInfo(xPlug, (uint)xMethodIdPlug, _MethodInfo.TypeEnum.Plug, null, xPlugAssembler); var xMethodInfo = new _MethodInfo(xMethod, (uint)xMethodIdMethod, xMethodType, xPlugInfo); if (xPlugAttrib.IsWildcard) { xPlugInfo.IsWildcard = true; xPlugInfo.PluggedMethod = xMethodInfo; var xInstructions = mReader.ProcessMethod(xPlug); if (xInstructions != null) { ProcessInstructions(xInstructions); mAsmblr.ProcessMethod(xPlugInfo, xInstructions); } } mAsmblr.GenerateMethodForward(xMethodInfo, xPlugInfo); } else { if (xInlineAttrib != null) { var xMethodID = mItemsList.IndexOf(xItem); if (xMethodID == -1) { throw new Exception("Method not in list!"); } xPlugInfo = new _MethodInfo(xPlug, (uint)xMethodID, _MethodInfo.TypeEnum.Plug, null, true); var xMethodInfo = new _MethodInfo(xMethod, (uint)xMethodIdMethod, xMethodType, xPlugInfo); xPlugInfo.PluggedMethod = xMethodInfo; var xInstructions = mReader.ProcessMethod(xPlug); if (xInstructions != null) { ProcessInstructions(xInstructions); mAsmblr.ProcessMethod(xPlugInfo, xInstructions); } mAsmblr.GenerateMethodForward(xMethodInfo, xPlugInfo); } else { xPlugInfo = new _MethodInfo(xPlug, (uint)xMethodIdPlug, _MethodInfo.TypeEnum.Plug, null, xPlugAssembler); var xMethodInfo = new _MethodInfo(xMethod, (uint)xMethodIdMethod, xMethodType, xPlugInfo); mAsmblr.GenerateMethodForward(xMethodInfo, xPlugInfo); } } } else { xPlugAttrib = xMethod.GetCustomAttribute <PlugMethod>(); if (xPlugAttrib != null) { if (xPlugAttrib.IsWildcard) { continue; } if (xPlugAttrib.PlugRequired) { throw new Exception(String.Format("Method {0} requires a plug, but none is implemented", xMethod.Name)); } xPlugAssembler = xPlugAttrib.Assembler; } var xMethodInfo = new _MethodInfo(xMethod, (uint)xMethodIdMethod, xMethodType, xPlugInfo, xPlugAssembler); var xInstructions = mReader.ProcessMethod(xMethod); if (xInstructions != null) { ProcessInstructions(xInstructions); mAsmblr.ProcessMethod(xMethodInfo, xInstructions); } } } else if (xItem is FieldInfo) { mAsmblr.ProcessField((FieldInfo)xItem); } } var xTypes = new HashSet <Type>(); var xMethods = new HashSet <MethodBase>(new MethodBaseComparer()); foreach (var xItem in mItems) { if (xItem is MethodBase) { xMethods.Add((MethodBase)xItem); } else if (xItem is Type) { xTypes.Add((Type)xItem); } } mAsmblr.GenerateVMTCode(xTypes, xMethods, GetTypeUID, GetMethodUID); }