Skip to content

Commit 8899edd

Browse files
committed
Refactored function generation
1 parent 9a8850a commit 8899edd

File tree

4 files changed

+137
-35
lines changed

4 files changed

+137
-35
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
using System.IO;
3+
4+
namespace Zydis.Generator.Core.CodeGeneration;
5+
6+
public sealed class CodeWriter
7+
{
8+
private const int IndentSize = 4;
9+
10+
private readonly TextWriter _writer;
11+
private string _indent;
12+
13+
public CodeWriter(TextWriter writer)
14+
{
15+
_writer = writer;
16+
_indent = "";
17+
}
18+
19+
public CodeWriter BeginBlock(bool indent = true)
20+
{
21+
_writer.Write(_indent);
22+
_writer.WriteLine('{');
23+
if (indent)
24+
{
25+
BeginIndent();
26+
}
27+
return this;
28+
}
29+
30+
public CodeWriter EndBlock(bool semicolon = false, bool indent = true)
31+
{
32+
if (indent)
33+
{
34+
EndIndent();
35+
}
36+
_writer.Write(_indent);
37+
_writer.WriteLine(semicolon ? "};" : "}");
38+
return this;
39+
}
40+
41+
public CodeWriter BeginIndent()
42+
{
43+
_indent = new string(' ', _indent.Length + IndentSize);
44+
return this;
45+
}
46+
47+
public CodeWriter EndIndent()
48+
{
49+
_indent = new string(' ', _indent.Length - IndentSize);
50+
return this;
51+
}
52+
53+
public CodeWriter Newline()
54+
{
55+
_writer.WriteLine();
56+
return this;
57+
}
58+
59+
public CodeWriter WriteLine(string text)
60+
{
61+
_writer.Write(_indent);
62+
_writer.WriteLine(text);
63+
return this;
64+
}
65+
66+
public CodeWriter WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, params object?[] arg)
67+
{
68+
_writer.Write(_indent);
69+
_writer.WriteLine(format, arg);
70+
return this;
71+
}
72+
}

src/Zydis.Generator.Core/Definitions/Builder/RelativeInfoRegistry.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System.Collections.Generic;
33
using System.Linq;
44

5+
using Zydis.Generator.Core.CodeGeneration;
6+
57
namespace Zydis.Generator.Core.Definitions.Builder;
68

79
internal sealed class RelativeInfoRegistry
@@ -12,9 +14,16 @@ internal sealed class RelativeInfoRegistry
1214

1315
internal sealed class RelInfo : IEquatable<RelInfo>
1416
{
17+
[Emittable(0)]
1518
public int[,] Size { get; private set; }
19+
20+
[Emittable(1, "accepts_scaling_hints")]
1621
public SizeHint SizeHint { get; init; }
22+
23+
[Emittable(2)]
1724
public bool AcceptsBranchHints { get; init; }
25+
26+
[Emittable(3)]
1827
public bool AcceptsBound { get; private set; }
1928

2029
public RelInfo(EncodableDefinition definition)

src/Zydis.Generator.Core/Definitions/Emitters/ConditionCodeEmitter.cs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.IO;
33
using System.Threading.Tasks;
44

5+
using Zydis.Generator.Core.CodeGeneration;
56
using Zydis.Generator.Core.Definitions.Builder;
67

78
namespace Zydis.Generator.Core.Definitions.Emitters;
@@ -13,24 +14,30 @@ public static async Task EmitAsync(StreamWriter writer, ConditionCodeRegistry re
1314
ArgumentNullException.ThrowIfNull(writer);
1415
ArgumentNullException.ThrowIfNull(registry);
1516

16-
// TODO: Add something to handle indentation automatically
17-
writer.WriteLine("ZyanBool ZydisGetCcInfo(ZydisMnemonic mnemonic, ZydisSourceConditionCode *scc)");
18-
writer.WriteLine("{");
19-
writer.WriteLine(" switch (mnemonic)");
20-
writer.WriteLine(" {");
17+
var codeWriter = new CodeWriter(writer);
18+
codeWriter
19+
.WriteLine("ZyanBool ZydisGetCcInfo(ZydisMnemonic mnemonic, ZydisSourceConditionCode *scc)")
20+
.BeginBlock()
21+
.WriteLine("switch (mnemonic)")
22+
.BeginBlock(false);
2123
foreach (var info in registry.ConditionCodeInfos)
2224
{
2325
foreach (var mnemonic in info.Mnemonics)
2426
{
25-
writer.WriteLine(" case ZYDIS_MNEMONIC_{0}:", mnemonic.ToUpperInvariant());
27+
codeWriter.WriteLine("case ZYDIS_MNEMONIC_{0}:", mnemonic.ToUpperInvariant());
2628
}
27-
writer.WriteLine(" *scc = {0};", info.Scc);
28-
writer.WriteLine(" return ZYAN_TRUE;");
29+
codeWriter
30+
.BeginIndent()
31+
.WriteLine("*scc = {0};", info.Scc)
32+
.WriteLine("return ZYAN_TRUE;")
33+
.EndIndent();
2934
}
30-
writer.WriteLine(" default:");
31-
writer.WriteLine(" *scc = ZYDIS_SCC_NONE;");
32-
writer.WriteLine(" return ZYAN_FALSE;");
33-
writer.WriteLine(" }");
34-
writer.WriteLine("}");
35+
codeWriter
36+
.WriteLine("default:")
37+
.BeginIndent()
38+
.WriteLine("*scc = ZYDIS_SCC_NONE;")
39+
.WriteLine("return ZYAN_FALSE;")
40+
.EndBlock()
41+
.EndBlock();
3542
}
3643
}

src/Zydis.Generator.Core/Definitions/Emitters/RelativeInfoEmitter.cs

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
using Zydis.Generator.Core.CodeGeneration;
66
using Zydis.Generator.Core.Definitions.Builder;
77

8+
using static Zydis.Generator.Core.CodeGeneration.ObjectDeclaration;
9+
using static Zydis.Generator.Core.Definitions.Builder.RelativeInfoRegistry;
10+
811
namespace Zydis.Generator.Core.Definitions.Emitters;
912

1013
internal sealed class RelativeInfoEmitter
@@ -14,44 +17,55 @@ public static async Task EmitAsync(StreamWriter writer, RelativeInfoRegistry reg
1417
ArgumentNullException.ThrowIfNull(writer);
1518
ArgumentNullException.ThrowIfNull(registry);
1619

17-
// TODO: Add something to handle indentation automatically
18-
writer.WriteLine("const ZydisEncoderRelInfo *ZydisGetRelInfo(ZydisMnemonic mnemonic)");
19-
writer.WriteLine("{");
20-
writer.WriteLine(" static const ZydisEncoderRelInfo info_lookup[{0}] =", registry.Infos.Count);
21-
writer.WriteLine(" {");
20+
var codeWriter = new CodeWriter(writer);
21+
codeWriter
22+
.WriteLine("const ZydisEncoderRelInfo *ZydisGetRelInfo(ZydisMnemonic mnemonic)")
23+
.BeginBlock()
24+
.WriteLine("static const ZydisEncoderRelInfo info_lookup[{0}] =", registry.Infos.Count)
25+
.BeginBlock();
26+
var relInfoDeclaration = new ObjectDeclaration<RelInfo>(InitializerType.Positional);
27+
var sizeArrayDeclaration = new ArrayObjectDeclaration(3);
2228

2329
foreach (var info in registry.Infos)
2430
{
25-
var lookup = "";
31+
var relInfoEntry = new ObjectWriter(relInfoDeclaration, null);
32+
var sizeEntry = new ObjectWriter(sizeArrayDeclaration, null);
2633
for (var i = 0; i < info.Size.GetLength(0); ++i)
2734
{
28-
lookup += $"{{ {info.Size[i, 0]}, {info.Size[i, 1]}, {info.Size[i, 2]} }}, ";
35+
sizeEntry.WriteIntegerArray(i, info.Size[i, 0], info.Size[i, 1], info.Size[i, 2]);
2936
}
30-
writer.Write(" {{ {{ {0} }}, ZYDIS_SIZE_HINT_{1}, ", lookup[..^2], info.SizeHint.ToZydisString());
31-
WriterExtensions.WriteBool(writer, info.AcceptsBranchHints);
32-
writer.Write(", ");
33-
WriterExtensions.WriteBool(writer, info.AcceptsBound);
34-
writer.WriteLine(" },");
37+
relInfoEntry
38+
.WriteObject("size", sizeEntry)
39+
.WriteExpression("accepts_scaling_hints", "ZYDIS_SIZE_HINT_{0}", info.SizeHint.ToZydisString())
40+
.WriteBool("accepts_branch_hints", info.AcceptsBranchHints)
41+
.WriteBool("accepts_bound", info.AcceptsBound);
42+
codeWriter.WriteLine("{0},", relInfoEntry.GetExpression());
3543
}
3644

37-
writer.WriteLine(" };");
38-
writer.WriteLine("");
39-
writer.WriteLine(" switch (mnemonic)");
40-
writer.WriteLine(" {");
45+
codeWriter
46+
.EndBlock(true)
47+
.Newline()
48+
.WriteLine("switch (mnemonic)")
49+
.BeginBlock(false);
4150

4251
var info_index = 0;
4352
foreach (var mnemonics in registry.Mnemonics)
4453
{
4554
foreach (var mnemonic in mnemonics)
4655
{
47-
writer.WriteLine(" case ZYDIS_MNEMONIC_{0}:", mnemonic.ToUpperInvariant());
56+
codeWriter.WriteLine("case ZYDIS_MNEMONIC_{0}:", mnemonic.ToUpperInvariant());
4857
}
49-
writer.WriteLine(" return &info_lookup[{0}];", info_index++);
58+
codeWriter
59+
.BeginIndent()
60+
.WriteLine("return &info_lookup[{0}];", info_index++)
61+
.EndIndent();
5062
}
5163

52-
writer.WriteLine(" default:");
53-
writer.WriteLine(" return ZYAN_NULL;");
54-
writer.WriteLine(" }");
55-
writer.WriteLine("}");
64+
codeWriter
65+
.WriteLine("default:")
66+
.BeginIndent()
67+
.WriteLine("return ZYAN_NULL;")
68+
.EndBlock()
69+
.EndBlock();
5670
}
5771
}

0 commit comments

Comments
 (0)