Example #1
0
        public static uint GetStackCountForLocal(_MethodInfo aMethod, Type aField)
        {
            var xSize   = SizeOfType(aField);
            var xResult = xSize / 4;

            if (xSize % 4 != 0)
            {
                xResult++;
            }
            return(xResult);
        }
Example #2
0
        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);
        }
Example #3
0
        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;
            }
        }
Example #4
0
 public _MethodInfo(MethodBase aMethodBase, UInt32 aUID, TypeEnum aType, _MethodInfo aPlugMethod, Type aMethodAssembler) : this(aMethodBase, aUID, aType, aPlugMethod, false)
 {
     MethodAssembler = aMethodAssembler;
 }
Example #5
0
 protected static void Jump_End(_MethodInfo aMethod)
 {
     XS.Jump(GetLabel(aMethod) + AppAssembler.EndOfMethodLabelNameNormal);
 }
Example #6
0
 protected static void Jump_Exception(_MethodInfo aMethod)
 {
     // todo: port to numeric labels
     XS.Jump(GetLabel(aMethod) + AppAssembler.EndOfMethodLabelNameException);
 }
Example #7
0
 public static string GetLabel(_MethodInfo aMethod, int aPos)
 {
     return(LabelName.Get(GetLabel(aMethod), aPos));
 }
Example #8
0
 public static string GetLabel(_MethodInfo aMethod, ILOpCode aOpCode)
 {
     return(GetLabel(aMethod, aOpCode.Position));
 }
Example #9
0
        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);
                    }
                }
            }
        }
Example #10
0
 // 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);
Example #11
0
        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);
        }