forked from ryzendew/Ryujinx
-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make HLE project AOT friendly (#7085)
* add hle service generator remove usage of reflection in device state * remove rd.xml generation * make applet manager reflection free * fix typos * fix encoding * fix style report * remove rogue generator reference * remove double assignment
- Loading branch information
Showing
11 changed files
with
215 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using System.Text; | ||
|
||
namespace Ryujinx.HLE.Generators | ||
{ | ||
class CodeGenerator | ||
{ | ||
private const int IndentLength = 4; | ||
|
||
private readonly StringBuilder _sb; | ||
private int _currentIndentCount; | ||
|
||
public CodeGenerator() | ||
{ | ||
_sb = new StringBuilder(); | ||
} | ||
|
||
public void EnterScope(string header = null) | ||
{ | ||
if (header != null) | ||
{ | ||
AppendLine(header); | ||
} | ||
|
||
AppendLine("{"); | ||
IncreaseIndentation(); | ||
} | ||
|
||
public void LeaveScope(string suffix = "") | ||
{ | ||
DecreaseIndentation(); | ||
AppendLine($"}}{suffix}"); | ||
} | ||
|
||
public void IncreaseIndentation() | ||
{ | ||
_currentIndentCount++; | ||
} | ||
|
||
public void DecreaseIndentation() | ||
{ | ||
if (_currentIndentCount - 1 >= 0) | ||
{ | ||
_currentIndentCount--; | ||
} | ||
} | ||
|
||
public void AppendLine() | ||
{ | ||
_sb.AppendLine(); | ||
} | ||
|
||
public void AppendLine(string text) | ||
{ | ||
_sb.Append(' ', IndentLength * _currentIndentCount); | ||
_sb.AppendLine(text); | ||
} | ||
|
||
public override string ToString() | ||
{ | ||
return _sb.ToString(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using System.Linq; | ||
|
||
namespace Ryujinx.HLE.Generators | ||
{ | ||
[Generator] | ||
public class IpcServiceGenerator : ISourceGenerator | ||
{ | ||
public void Execute(GeneratorExecutionContext context) | ||
{ | ||
var syntaxReceiver = (ServiceSyntaxReceiver)context.SyntaxReceiver; | ||
CodeGenerator generator = new CodeGenerator(); | ||
|
||
generator.AppendLine("using System;"); | ||
generator.EnterScope($"namespace Ryujinx.HLE.HOS.Services.Sm"); | ||
generator.EnterScope($"partial class IUserInterface"); | ||
|
||
generator.EnterScope($"public IpcService? GetServiceInstance(Type type, ServiceCtx context, object? parameter = null)"); | ||
foreach (var className in syntaxReceiver.Types) | ||
{ | ||
if (className.Modifiers.Any(SyntaxKind.AbstractKeyword) || className.Modifiers.Any(SyntaxKind.PrivateKeyword) || !className.AttributeLists.Any(x => x.Attributes.Any(y => y.ToString().StartsWith("Service")))) | ||
continue; | ||
var name = GetFullName(className, context).Replace("global::", ""); | ||
if (!name.StartsWith("Ryujinx.HLE.HOS.Services")) | ||
continue; | ||
var constructors = className.ChildNodes().Where(x => x.IsKind(SyntaxKind.ConstructorDeclaration)).Select(y => y as ConstructorDeclarationSyntax); | ||
|
||
if (!constructors.Any(x => x.ParameterList.Parameters.Count >= 1)) | ||
continue; | ||
|
||
if (constructors.Where(x => x.ParameterList.Parameters.Count >= 1).FirstOrDefault().ParameterList.Parameters[0].Type.ToString() == "ServiceCtx") | ||
{ | ||
generator.EnterScope($"if (type == typeof({GetFullName(className, context)}))"); | ||
if (constructors.Any(x => x.ParameterList.Parameters.Count == 2)) | ||
{ | ||
var type = constructors.Where(x => x.ParameterList.Parameters.Count == 2).FirstOrDefault().ParameterList.Parameters[1].Type; | ||
var model = context.Compilation.GetSemanticModel(type.SyntaxTree); | ||
var typeSymbol = model.GetSymbolInfo(type).Symbol as INamedTypeSymbol; | ||
var fullName = typeSymbol.ToString(); | ||
generator.EnterScope("if (parameter != null)"); | ||
generator.AppendLine($"return new {GetFullName(className, context)}(context, ({fullName})parameter);"); | ||
generator.LeaveScope(); | ||
} | ||
|
||
if (constructors.Any(x => x.ParameterList.Parameters.Count == 1)) | ||
{ | ||
generator.AppendLine($"return new {GetFullName(className, context)}(context);"); | ||
} | ||
|
||
generator.LeaveScope(); | ||
} | ||
} | ||
|
||
generator.AppendLine("return null;"); | ||
generator.LeaveScope(); | ||
|
||
generator.LeaveScope(); | ||
generator.LeaveScope(); | ||
context.AddSource($"IUserInterface.g.cs", generator.ToString()); | ||
} | ||
|
||
private string GetFullName(ClassDeclarationSyntax syntaxNode, GeneratorExecutionContext context) | ||
{ | ||
var typeSymbol = context.Compilation.GetSemanticModel(syntaxNode.SyntaxTree).GetDeclaredSymbol(syntaxNode); | ||
|
||
return typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); | ||
} | ||
|
||
public void Initialize(GeneratorInitializationContext context) | ||
{ | ||
context.RegisterForSyntaxNotifications(() => new ServiceSyntaxReceiver()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules> | ||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> | ||
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath> | ||
<IsRoslynComponent>true</IsRoslynComponent> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers"> | ||
<PrivateAssets>all</PrivateAssets> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
</PackageReference> | ||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using System.Collections.Generic; | ||
|
||
namespace Ryujinx.HLE.Generators | ||
{ | ||
internal class ServiceSyntaxReceiver : ISyntaxReceiver | ||
{ | ||
public HashSet<ClassDeclarationSyntax> Types = new HashSet<ClassDeclarationSyntax>(); | ||
|
||
public void OnVisitSyntaxNode(SyntaxNode syntaxNode) | ||
{ | ||
if (syntaxNode is ClassDeclarationSyntax classDeclaration) | ||
{ | ||
if (classDeclaration.BaseList == null) | ||
{ | ||
return; | ||
} | ||
|
||
Types.Add(classDeclaration); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters