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