예제 #1
0
 public AstNodeExpr MemoryGetPointer(PspMemory memory, AstNodeExpr address, bool safe,
                                     string errorDescription = "ERROR", InvalidAddressAsEnum invalidAddress = InvalidAddressAsEnum.Exception)
 {
     if (safe)
     {
         return(Ast.CallInstance(
                    Ast.CpuThreadStateExpr,
                    (AddressToPointerWithErrorFunc)CpuThreadState.Methods.GetMemoryPtrSafeWithError,
                    Ast.Cast <uint>(address),
                    errorDescription,
                    true,
                    Ast.Immediate(invalidAddress)
                    ));
     }
     else
     {
         if (DynarecConfig.AllowFastMemory && memory.HasFixedGlobalAddress)
         {
             if (DynarecConfig.EnableFastPspMemoryUtilsGetFastMemoryReader)
             {
                 return(Ast.CallStatic(FastPspMemoryUtils.GetFastMemoryReader(memory.FixedGlobalAddress),
                                       address));
             }
             else
             {
                 var addressMasked = Ast.Binary(address, "&", Ast.Immediate(FastPspMemory.FastMemoryMask));
                 return(Ast.Immediate(memory.FixedGlobalAddress) + addressMasked);
             }
         }
         else
         {
             return(Ast.CallInstance(
                        Ast.CpuThreadStateExpr,
                        (AddressToPointerFunc)CpuThreadState.Methods.GetMemoryPtr,
                        address
                        ));
         }
     }
 }
        private AstNodeStmContainer CreateDelegateForMethodInfoPriv(MethodInfo MethodInfo,
                                                                    HlePspFunctionAttribute HlePspFunctionAttribute, out List <ParamInfo> OutParamInfoList)
        {
            var RegisterReader = new AstRegisterReader(MethodInfo, Memory);

            OutParamInfoList = RegisterReader.ParamInfoList;

            //var SafeILGenerator = MipsMethodEmiter.SafeILGenerator;

            var AstNodes = new AstNodeStmContainer();

            AstNodes.AddStatement(ast.Comment("HleModuleHost.CreateDelegateForMethodInfo(" + MethodInfo + ", " +
                                              HlePspFunctionAttribute + ")"));

            AstNodeExprCall AstMethodCall;

            {
                //var ModuleObject = this.Cast(this.GetType(), this.FieldAccess(this.Argument<CpuThreadState>(0, "CpuThreadState"), "ModuleObject"));
                //SafeILGenerator.LoadArgument0CpuThreadState();
                //SafeILGenerator.LoadField(typeof(CpuThreadState).GetField("ModuleObject"));
                //SafeILGenerator.CastClass(this.GetType());

                var AstParameters = new List <AstNodeExpr>();

                foreach (var ParameterInfo in MethodInfo.GetParameters())
                {
                    var ParameterType = ParameterInfo.ParameterType;

                    var HleInvalidAsNullAttribute           = ParameterInfo.GetCustomAttribute <HleInvalidAsNullAttribute>();
                    var HleInvalidAsInvalidPointerAttribute =
                        ParameterInfo.GetCustomAttribute <HleInvalidAsInvalidPointerAttribute>();
                    InvalidAddressAsEnum InvalidAddressAsEnum = InvalidAddressAsEnum.Exception;
                    if (HleInvalidAsNullAttribute != null)
                    {
                        InvalidAddressAsEnum = InvalidAddressAsEnum.Null;
                    }
                    if (HleInvalidAsInvalidPointerAttribute != null)
                    {
                        InvalidAddressAsEnum = InvalidAddressAsEnum.InvalidAddress;
                    }

                    // The CpuThreadState
                    if (ParameterType == typeof(CpuThreadState))
                    {
                        AstParameters.Add(ast.CpuThreadStateExpr);
                    }
                    // A stringz
                    else if (ParameterType == typeof(string))
                    {
                        AstParameters.Add(
                            ast.CallStatic(
                                (Func <CpuThreadState, uint, string>)HleModuleHost.StringFromAddress,
                                ast.CpuThreadStateExpr,
                                RegisterReader.Read <uint>(ParameterInfo)
                                )
                            );
                    }
                    // A pointer or ref/out
                    else if (ParameterType.IsPointer || ParameterType.IsByRef)
                    {
                        AstParameters.Add(
                            ast.Cast(
                                ParameterType,
                                ast.MemoryGetPointer(
                                    CpuProcessor.Memory,
                                    RegisterReader.Read <uint>(ParameterInfo),
                                    safe: true,
                                    errorDescription: "Invalid Pointer for Argument '" + ParameterType.Name + " " +
                                    ParameterInfo.Name + "'",
                                    invalidAddress: InvalidAddressAsEnum
                                    )
                                )
                            );
                    }
                    // A long type
                    else if (ParameterType == typeof(long) || ParameterType == typeof(ulong))
                    {
                        AstParameters.Add(RegisterReader.Read(ParameterInfo));
                    }
                    // A float register.
                    else if (ParameterType == typeof(float))
                    {
                        AstParameters.Add(RegisterReader.Read(ParameterInfo));
                    }
                    // PspPointer
                    else if (ParameterType == typeof(PspPointer))
                    {
                        AstParameters.Add(ast.CallStatic(
                                              typeof(PspPointer).GetMethod("op_Implicit", new[] { typeof(uint) }),
                                              RegisterReader.Read <uint>(ParameterInfo)
                                              ));
                    }
                    // A class
                    else if (ParameterType.IsClass)
                    {
                        if (!ParameterType.Implements(typeof(IHleUidPoolClass)))
                        {
                            throw (new InvalidCastException(
                                       $"Can't use a class '{ParameterType}' not implementing IHleUidPoolClass as parameter"));
                        }

                        AstParameters.Add(ast.Cast(ParameterType, ast.CallStatic(
                                                       (Func <CpuThreadState, Type, int, bool, object>)GetObjectFromPoolHelper,
                                                       ast.CpuThreadStateExpr,
                                                       ast.Immediate(ParameterType),
                                                       RegisterReader.Read <int>(ParameterInfo),
                                                       (InvalidAddressAsEnum == InvalidAddressAsEnum.Null)
                                                       )));
                    }
                    // An integer register
                    else
                    {
                        AstParameters.Add(ast.Cast(ParameterType,
                                                   RegisterReader.Read((ParameterType == typeof(uint)) ? typeof(uint) : typeof(int),
                                                                       ParameterInfo)));
                    }
                }

                AstMethodCall = ast.CallInstance(
                    ThisILInstanceHolder.GetAstFieldAccess(),
                    MethodInfo,
                    AstParameters.ToArray()
                    );
            }

            if (AstMethodCall.Type == typeof(void))
            {
                AstNodes.AddStatement(ast.Statement(AstMethodCall));
            }
            else if (AstMethodCall.Type == typeof(long))
            {
                AstNodes.AddStatement(ast.Assign(ast.GPR_l(2), ast.Cast <long>(AstMethodCall)));
            }
            else if (AstMethodCall.Type == typeof(float))
            {
                AstNodes.AddStatement(ast.Assign(ast.Fpr(0), ast.Cast <float>(AstMethodCall)));
            }
            else if (AstMethodCall.Type.IsClass)
            {
                if (!AstMethodCall.Type.Implements(typeof(IHleUidPoolClass)))
                {
                    throw (new InvalidCastException(
                               $"Can't use a class '{AstMethodCall.Type}' not implementing IHleUidPoolClass as return value"));
                }
                AstNodes.AddStatement(ast.Assign(
                                          ast.Gpr(2),
                                          ast.CallStatic(
                                              (Func <CpuThreadState, Type, IHleUidPoolClass, uint>)GetOrAllocIndexFromPoolHelper,
                                              ast.CpuThreadStateExpr,
                                              ast.Immediate(AstMethodCall.Type),
                                              ast.Cast <IHleUidPoolClass>(AstMethodCall)
                                              )
                                          ));
            }
            else
            {
                AstNodes.AddStatement(ast.Assign(ast.Gpr(2), ast.Cast <uint>(AstMethodCall)));
            }

            return(AstNodes);
        }
예제 #3
0
 public void* GetMemoryPtrSafeWithError(uint Address, String ErrorDescription, bool CanBeNull, InvalidAddressAsEnum Invalid)
 {
     //Console.Error.WriteLine("{0:X8}, {1}, {2}", Address, CanBeNull, InvalidAsNull);
     try
     {
         void* Result = Memory.PspAddressToPointerSafe(Address, 0, CanBeNull);
         /*
         if (Result == null && !CanBeNull)
         {
             throw(new PspMemory.InvalidAddressException(""));
         }
         */
         return Result;
     }
     catch (InvalidAddressException InvalidAddressException)
     {
         if (Invalid == InvalidAddressAsEnum.Null) return null;
         if (Invalid == InvalidAddressAsEnum.InvalidAddress) return PspMemory.InvalidPointer;
         throw (new InvalidAddressException("GetMemoryPtrSafeWithError:" + ErrorDescription + " : " + InvalidAddressException.Message, InvalidAddressException));
     }
     catch (Exception Exception)
     {
         if (Invalid == InvalidAddressAsEnum.Null) return null;
         if (Invalid == InvalidAddressAsEnum.InvalidAddress) return PspMemory.InvalidPointer;
         throw (new Exception("GetMemoryPtrSafeWithError: " + ErrorDescription + " : " + Exception.Message, Exception));
     }
 }