Exemplo n.º 1
0
        public void CreateDelegateTest()
        {
            var PspConfig          = new PspConfig();
            var PspEmulatorContext = new PspEmulatorContext(PspConfig);

            PspEmulatorContext.SetInstanceType <PspMemory, LazyPspMemory>();
            var Memory         = PspEmulatorContext.GetInstance <PspMemory>();
            var Processor      = PspEmulatorContext.GetInstance <CpuProcessor>();
            var CpuThreadState = new CpuThreadState(Processor);
            var MipsEmiter     = new MipsMethodEmiter(new MipsEmiter(), Processor);

            CpuThreadState.GPR[1] = 1;
            CpuThreadState.GPR[2] = 2;
            CpuThreadState.GPR[3] = 3;
            MipsEmiter.OP_3REG_Unsigned(1, 2, 2, OpCodes.Add);
            MipsEmiter.OP_3REG_Unsigned(0, 2, 2, OpCodes.Add);
            MipsEmiter.OP_2REG_IMM_Signed(10, 0, 1000, OpCodes.Add);
            MipsEmiter.CreateDelegate()(CpuThreadState);
            Assert.AreEqual(4, CpuThreadState.GPR[1]);
            Assert.AreEqual(0, CpuThreadState.GPR[0]);
            Assert.AreEqual(1000, CpuThreadState.GPR[10]);
        }
Exemplo n.º 2
0
        private Action <CpuThreadState> CreateDelegateForMethodInfo(MethodInfo MethodInfo, HlePspFunctionAttribute HlePspFunctionAttribute)
        {
            var MipsMethodEmiter = new MipsMethodEmiter(HleState.MipsEmiter, HleState.CpuProcessor);
            int GprIndex         = 4;
            int FprIndex         = 0;

            var  NotImplementedAttribute = (HlePspNotImplementedAttribute)MethodInfo.GetCustomAttributes(typeof(HlePspNotImplementedAttribute), true).FirstOrDefault();
            bool NotImplemented          = (NotImplementedAttribute != null) ? NotImplementedAttribute.Notice : false;
            bool SkipLog = HlePspFunctionAttribute.SkipLog;

            var ParamInfoList = new List <ParamInfo>();

            Action CallAction = () =>
            {
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldarg_0);
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldfld, typeof(CpuThreadState).GetField("ModuleObject"));
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Castclass, this.GetType());
                foreach (var ParameterInfo in MethodInfo.GetParameters())
                {
                    var ParameterType = ParameterInfo.ParameterType;

                    // The CpuThreadState
                    if (ParameterType == typeof(CpuThreadState))
                    {
                        MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldarg_0);
                    }
                    // A stringz
                    else if (ParameterType == typeof(string))
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType  = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = ParameterType,
                        });
                        MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldarg_0);
                        MipsMethodEmiter.LoadGPR_Unsigned(GprIndex);
                        MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, typeof(HleModuleHost).GetMethod("StringFromAddress"));
                        GprIndex++;
                    }
                    // A pointer
                    else if (ParameterType.IsPointer)
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType  = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = typeof(uint),
                        });
                        MipsMethodEmiter._getmemptr(() =>
                        {
                            MipsMethodEmiter.LoadGPR_Unsigned(GprIndex);
                        }, Safe: true);
                        GprIndex++;
                    }
                    // A long type
                    else if (ParameterType == typeof(long) || ParameterType == typeof(ulong))
                    {
                        while (GprIndex % 2 != 0)
                        {
                            GprIndex++;
                        }

                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType  = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = ParameterType,
                        });


                        MipsMethodEmiter.LoadGPRLong_Signed(GprIndex + 0);

                        /*
                         * MipsMethodEmiter.LoadGPR_Unsigned(GprIndex + 0);
                         * MipsMethodEmiter.LoadGPR_Unsigned(GprIndex + 1);
                         * MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, 32);
                         * MipsMethodEmiter.ILGenerator.Emit(OpCodes.Shl);
                         * MipsMethodEmiter.ILGenerator.Emit(OpCodes.Or);
                         */
                        GprIndex += 2;
                    }
                    // A float register.
                    else if (ParameterType == typeof(float))
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType  = ParamInfo.RegisterTypeEnum.Fpr,
                            RegisterIndex = FprIndex,
                            ParameterType = ParameterType,
                        });

                        MipsMethodEmiter.LoadFPR(FprIndex);
                        FprIndex++;
                    }
                    // An integer register
                    else
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType  = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = ParameterType,
                        });

                        MipsMethodEmiter.LoadGPR_Unsigned(GprIndex);
                        GprIndex++;
                    }
                    //MipsMethodEmiter.ILGenerator.Emit(OpCodes.ld
                }
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, MethodInfo);
            };

            if (MethodInfo.ReturnType == typeof(void))
            {
                CallAction();
            }
            else if (MethodInfo.ReturnType == typeof(long))
            {
                MipsMethodEmiter.SaveGPRLong(2, CallAction);
            }
            else
            {
                MipsMethodEmiter.SaveGPR(2, CallAction);
            }

            var Delegate = MipsMethodEmiter.CreateDelegate();

            return((CpuThreadState) =>
            {
                bool Trace = (!SkipLog && CpuThreadState.CpuProcessor.PspConfig.DebugSyscalls);

                if (NotImplemented)
                {
                    Trace = true;
                    ConsoleUtils.SaveRestoreConsoleState(() =>
                    {
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine(
                            "Not implemented {0}.{1}",
                            MethodInfo.DeclaringType.Name, MethodInfo.Name
                            );
                    });
                }

                var Out = Console.Out;
                if (NotImplemented)
                {
                    Out = Console.Error;
                }

                if (Trace)
                {
                    if (HleState.ThreadManager.Current != null)
                    {
                        Out.Write(
                            "Thread({0}:'{1}') : RA(0x{2:X})",
                            HleState.ThreadManager.Current.Id,
                            HleState.ThreadManager.Current.Name,
                            HleState.ThreadManager.Current.CpuThreadState.RA
                            );
                    }
                    else
                    {
                        Out.Write("NoThread:");
                    }
                    Out.Write(" : {0}.{1}", MethodInfo.DeclaringType.Name, MethodInfo.Name);
                    Out.Write("(");
                    int Count = 0;
                    foreach (var ParamInfo in ParamInfoList)
                    {
                        if (Count > 0)
                        {
                            Out.Write(", ");
                        }
                        Out.Write("{0}:", ParamInfo.ParameterName);
                        switch (ParamInfo.RegisterType)
                        {
                        case HleModuleHost.ParamInfo.RegisterTypeEnum.Fpr:
                        case HleModuleHost.ParamInfo.RegisterTypeEnum.Gpr:
                            uint Int4 = (uint)CpuThreadState.GPR[ParamInfo.RegisterIndex];
                            uint Float4 = (uint)CpuThreadState.FPR[ParamInfo.RegisterIndex];
                            Out.Write("{0}", ToNormalizedTypeString(ParamInfo.ParameterType, CpuThreadState, Int4, Float4));
                            break;

                        default:
                            throw(new NotImplementedException());
                        }
                        Count++;
                    }
                    Out.Write(")");
                    //Console.WriteLine("");
                }

                CpuThreadState.ModuleObject = this;
                try
                {
                    Delegate(CpuThreadState);
                }
                catch (SceKernelException SceKernelException)
                {
                    CpuThreadState.GPR[2] = (int)SceKernelException.SceKernelError;
                }
                catch (SceKernelSelfStopUnloadModuleException SceKernelSelfStopUnloadModuleException)
                {
                    throw (SceKernelSelfStopUnloadModuleException);
                }
                catch (Exception Exception)
                {
                    throw (new Exception(
                               String.Format("ERROR calling {0}.{1}!", MethodInfo.DeclaringType.Name, MethodInfo.Name),
                               Exception
                               ));
                }
                finally
                {
                    if (Trace)
                    {
                        Out.WriteLine(" : {0}", ToNormalizedTypeString(MethodInfo.ReturnType, CpuThreadState, (uint)CpuThreadState.GPR[2], (float)CpuThreadState.FPR[0]));
                        Out.WriteLine("");
                    }
                }
            });
        }