private Action <CpuThreadState> CreateDelegateForMethodInfo(MethodInfo MethodInfo, HlePspFunctionAttribute HlePspFunctionAttribute) { if (!MethodInfo.DeclaringType.IsAssignableFrom(this.GetType())) { throw (new Exception($"Invalid {MethodInfo.DeclaringType} != {this.GetType()}")); } bool SkipLog = HlePspFunctionAttribute.SkipLog; var NotImplementedAttribute = (HlePspNotImplementedAttribute)MethodInfo .GetCustomAttributes(typeof(HlePspNotImplementedAttribute), true).FirstOrDefault(); bool NotImplementedFunc = (NotImplementedAttribute != null) && NotImplementedAttribute.Notice; List <ParamInfo> ParamInfoList; var AstNodes = AstOptimizerPsp.GlobalOptimize( CpuProcessor, ast.Statements( // Do stuff before CreateDelegateForMethodInfoPriv(MethodInfo, HlePspFunctionAttribute, out ParamInfoList) // Do stuff after ) ); var Delegate = AstNodeExtensions.GeneratorIlPsp.GenerateDelegate <Action <CpuThreadState> >( $"Proxy_{this.GetType().Name}_{MethodInfo.Name}", AstNodes ); //return Delegate; return((CpuThreadState) => { bool Trace = (!SkipLog && CpuThreadState.CpuProcessor.CpuConfig.DebugSyscalls); bool NotImplemented = NotImplementedFunc && HleConfig.DebugNotImplemented; if (Trace && (MethodInfo.DeclaringType.Name == "Kernel_Library")) { Trace = false; } //Console.WriteLine("aaaaaaaaaaaaa"); 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 (ThreadManager.Current != null) { Out.Write( "Thread({0}:'{1}') : RA(0x{2:X})", ThreadManager.Current.Id, ThreadManager.Current.Name, ThreadManager.Current.CpuThreadState.Ra ); } else { Out.Write("NoThread:"); } Out.Write(" : {0}.{1}", MethodInfo.DeclaringType.Name, MethodInfo.Name); Out.Write("("); int Count = 0; var NormalRegisterReader = new NormalRegisterReader(CpuThreadState); foreach (var ParamInfo in ParamInfoList) { if (Count > 0) { Out.Write(", "); } Out.Write("{0}:", ParamInfo.ParameterInfo.Name); switch (ParamInfo.RegisterType) { case HleModuleHost.ParamInfo.RegisterTypeEnum.Fpr: case HleModuleHost.ParamInfo.RegisterTypeEnum.Gpr: var Object = NormalRegisterReader.Read <uint>(ParamInfo.ParameterInfo); Out.Write("{0}", ToNormalizedTypeString(ParamInfo.ParameterInfo.ParameterType, CpuThreadState, Object)); break; default: throw (new NotImplementedException()); } Count++; } Out.Write(")"); //Console.WriteLine(""); } try { CpuThreadState.Pc = CpuThreadState.Ra; Delegate(CpuThreadState); } catch (InvalidProgramException) { Console.WriteLine("CALLING: {0}", MethodInfo); Console.WriteLine("{0}", (new GeneratorCSharp()).GenerateRoot(AstNodes).ToString()); foreach (var Line in AstNodeExtensions.GeneratorIlPsp.GenerateToStringList(MethodInfo, AstNodes)) { Console.WriteLine(Line); } throw; } catch (MemoryPartitionNoMemoryException) { CpuThreadState.Gpr[2] = (int)SceKernelErrors.ERROR_ERRNO_NO_MEMORY; } catch (SceKernelException SceKernelException) { CpuThreadState.Gpr[2] = (int)SceKernelException.SceKernelError; } catch (SceKernelSelfStopUnloadModuleException) { throw; } #if !DO_NOT_PROPAGATE_EXCEPTIONS catch (Exception Exception) { throw (new Exception( $"ERROR calling {MethodInfo.DeclaringType.Name}.{MethodInfo.Name}!", Exception )); } #endif finally { if (Trace) { Out.WriteLine(" : {0}", ToNormalizedTypeString(MethodInfo.ReturnType, CpuThreadState, ((MethodInfo.ReturnType == typeof(float)) ? (object)CpuThreadState.Fpr[0] : (object)CpuThreadState.Gpr[2]))); Out.WriteLine(""); } } }); }
public Result CreateDelegate(AstNodeStm astNodeStm, int totalInstructions) { var time0 = DateTime.UtcNow; astNodeStm = AstOptimizerPsp.GlobalOptimize(_processor, Ast.Statements(astNodeStm, Ast.Return())); var time1 = DateTime.UtcNow; #if DEBUG_GENERATE_IL Console.WriteLine("{0}", GeneratorIL.GenerateToString <GeneratorILPsp>(DynamicMethod, AstNodeStm)); #endif #if DEBUG_GENERATE_IL_CSHARP Console.WriteLine("{0}", AstNodeExtensions.ToCSharpString(AstNodeStm).Replace("CpuThreadState.", "")); #endif Action <CpuThreadState> Delegate; var time2 = time1; var disableOptimizations = DynarecConfig.DisableDotNetJitOptimizations; if (totalInstructions >= DynarecConfig.InstructionCountToDisableOptimizations) { disableOptimizations = true; } if (Platform.IsMono) { disableOptimizations = false; } if (DynarecConfig.ForceJitOptimizationsOnEvenLargeFunctions) { disableOptimizations = false; } try { Delegate = MethodCreator.CreateDynamicMethod <Action <CpuThreadState> >( //Delegate = MethodCreator.CreateMethodInClass<Action<CpuThreadState>>( Assembly.GetExecutingAssembly().ManifestModule, $"DynamicMethod_0x{this._pc:X}", disableOptimizations, dynamicMethod => { astNodeStm.GenerateIl(dynamicMethod); time2 = DateTime.UtcNow; } ); } catch (InvalidProgramException) { Console.Error.WriteLine("Invalid Delegate:"); #if LOG_TRACE Console.WriteLine("Invalid Delegate:"); foreach (var Line in SafeILGenerator.GetEmittedInstructions()) { if (Line.Substr(0, 1) == ":") { Console.WriteLine("{0}", Line); } else { Console.WriteLine(" {0}", Line); } } #endif throw; } var time3 = DateTime.UtcNow; return(new Result { Delegate = Delegate, DisableOptimizations = disableOptimizations, TimeOptimize = time1 - time0, TimeGenerateIl = time2 - time1, TimeCreateDelegate = time3 - time2, }); }