Skip to content

Commit 77ed61f

Browse files
committed
[WIP] Compiles but applications won't build
1 parent 3f45767 commit 77ed61f

File tree

4 files changed

+142
-56
lines changed

4 files changed

+142
-56
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
3+
namespace Xamarin.Android.Tasks.LLVMIR;
4+
5+
class LlvmIrArraySection
6+
{
7+
public Type DataType { get; }
8+
public object? Data { get; }
9+
public string? Header { get; }
10+
11+
public LlvmIrArraySection (Type type, object? data, string? header = null)
12+
{
13+
DataType = type;
14+
Data = data;
15+
Header = header;
16+
}
17+
18+
public LlvmIrArraySection (object? data, string? header = null)
19+
: this ((data ?? throw new ArgumentNullException (nameof (data))).GetType (), data, header)
20+
{}
21+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace Xamarin.Android.Tasks.LLVMIR;
5+
6+
/// <summary>
7+
/// Represents a uniform array which is composed of several sections. Each section must contain
8+
/// entries of the same type (or derived from the same base type), has its own header but is otherwise
9+
/// treated as a separate entity to other sections. The resulting output array will look as a flattened
10+
/// array of arrays (sections).
11+
/// </summary>
12+
class LlvmIrSectionedArray
13+
{
14+
readonly Type containedType;
15+
readonly List<LlvmIrArraySection> sections = new ();
16+
17+
public List<LlvmIrArraySection> Sections => sections;
18+
19+
public LlvmIrSectionedArray (Type containedType)
20+
{
21+
this.containedType = containedType;
22+
}
23+
24+
public void Add (LlvmIrArraySection section)
25+
{
26+
if (!containedType.IsAssignableFrom (section.DataType)) {
27+
throw new ArgumentException ("must be of type {containedType} or derived from it", nameof (section));
28+
}
29+
30+
sections.Add (section);
31+
}
32+
}

src/Xamarin.Android.Build.Tasks/Utilities/LlvmIrGenerator/StructureInstance.cs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,32 @@
44

55
namespace Xamarin.Android.Tasks.LLVMIR
66
{
7+
enum StructureInstanceType
8+
{
9+
/// <summary>
10+
/// Instance describes actual data to be output. Guarantees that the
11+
/// <see cref="StructureInstance.Obj"/> property isn't `null`.
12+
/// </summary>
13+
Data,
14+
15+
/// <summary>
16+
/// Instance marks the beginning of section in an array of
17+
/// structures. Ignored if we're not outputting an array of structures.
18+
/// <see cref="StructureInstance.Obj"/> property will **always** be `null`
19+
/// in such instances.
20+
/// </summary>
21+
ArraySection,
22+
}
23+
724
abstract class StructureInstance
825
{
926
StructureInfo info;
1027

1128
public object? Obj { get; }
1229
public Type Type => info.Type;
1330
public StructureInfo Info => info;
31+
public StructureInstanceType InstanceType { get; }
32+
public string? Comment { get; }
1433

1534
/// <summary>
1635
/// Do **not** set this property, it is used internally by <see cref="LlvmIrModule.AddStructureArrayGlobalVariable"/>,
@@ -28,18 +47,27 @@ abstract class StructureInstance
2847
/// </summary>
2948
public bool IsZeroInitialized { get; set; }
3049

31-
protected StructureInstance (StructureInfo info, object instance)
50+
protected StructureInstance (StructureInfo info, object instance, string? comment = null)
3251
{
3352
if (instance == null) {
3453
throw new ArgumentNullException (nameof (instance));
3554
}
3655

56+
InstanceType = StructureInstanceType.Data;
3757
if (!info.Type.IsAssignableFrom (instance.GetType ())) {
3858
throw new ArgumentException ($"must be an instance of, or derived from, the {info.Type} type, or `null` (was {instance})", nameof (instance));
3959
}
4060

4161
this.info = info;
4262
Obj = instance;
63+
Comment = comment;
64+
}
65+
66+
protected StructureInstance (StructureInfo info, string? comment = null)
67+
{
68+
InstanceType = StructureInstanceType.ArraySection;
69+
this.info = info;
70+
Comment = comment;
4371
}
4472
}
4573

@@ -49,16 +77,20 @@ protected StructureInstance (StructureInfo info, object instance)
4977
/// only get in the way), but on the other hand we need to be able to get the structure type (whose instance is in
5078
/// <see cref="Obj"/> and <see cref="Instance"/>) only by looking at the **type**. This is needed in situations when we have
5179
/// an array of some structures that is empty - we wouldn't be able to gleam the structure type from any instance and we still
52-
/// need to output a stronly typed LLVM IR declaration of the structure array. With this class, most of the code will use the
80+
/// need to output a strongly typed LLVM IR declaration of the structure array. With this class, most of the code will use the
5381
/// abstract <see cref="StructureInstance"/> type, and knowing we have only one non-abstract implementation of the class allows
5482
/// us to use StructureInstance&lt;T&gt; in a cast, to get <c>T</c> via reflection.
5583
/// <summary>
5684
sealed class StructureInstance<T> : StructureInstance
5785
{
5886
public T? Instance => (T)Obj;
5987

60-
public StructureInstance (StructureInfo info, T instance)
61-
: base (info, instance)
88+
public StructureInstance (StructureInfo info, T instance, string? comment = null)
89+
: base (info, instance, comment)
90+
{}
91+
92+
public StructureInstance (StructureInfo info, string? comment = null)
93+
: base (info, comment)
6294
{}
6395
}
6496
}

src/Xamarin.Android.Build.Tasks/Utilities/TypeMappingReleaseNativeAssemblyGeneratorCLR.cs

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,6 @@ public override string GetComment (object data, string fieldName)
2929
return String.Empty;
3030
}
3131

32-
public override string? GetPointedToSymbolName (object data, string fieldName)
33-
{
34-
var map_module = EnsureType<TypeMapModule> (data);
35-
36-
if (String.Compare ("map", fieldName, StringComparison.Ordinal) == 0) {
37-
return map_module.MapSymbolName;
38-
}
39-
40-
if (String.Compare ("duplicate_map", fieldName, StringComparison.Ordinal) == 0) {
41-
return map_module.DuplicateMapSymbolName;
42-
}
43-
44-
return null;
45-
}
46-
4732
public override ulong GetBufferSize (object data, string fieldName)
4833
{
4934
var map_module = EnsureType<TypeMapModule> (data);
@@ -126,12 +111,6 @@ sealed class TypeMapModule
126111
[NativeAssembler (Ignore = true)]
127112
public Guid MVID;
128113

129-
[NativeAssembler (Ignore = true)]
130-
public string? MapSymbolName;
131-
132-
[NativeAssembler (Ignore = true)]
133-
public string? DuplicateMapSymbolName;
134-
135114
[NativeAssembler (Ignore = true)]
136115
public TypeMapGenerator.ModuleReleaseData Data;
137116

@@ -147,11 +126,11 @@ sealed class TypeMapModule
147126
public uint assembly_name_index;
148127
public uint assembly_name_length;
149128

150-
[NativeAssembler (UsesDataProvider = true), NativePointer (PointsToSymbol = "")]
151-
public TypeMapModuleEntry map;
129+
[NativeAssembler (UsesDataProvider = true)]
130+
public uint map_index;
152131

153-
[NativeAssembler (UsesDataProvider = true), NativePointer (PointsToSymbol = "")]
154-
public TypeMapModuleEntry duplicate_map;
132+
[NativeAssembler (UsesDataProvider = true)]
133+
public uint duplicate_map_index;
155134
}
156135

157136
// Order of fields and their type must correspond *exactly* to that in
@@ -187,12 +166,10 @@ sealed class TypeMapJava
187166

188167
sealed class ModuleMapData
189168
{
190-
public string SymbolLabel { get; }
191169
public List<StructureInstance<TypeMapModuleEntry>> Entries { get; }
192170

193-
public ModuleMapData (string symbolLabel, List<StructureInstance<TypeMapModuleEntry>> entries)
171+
public ModuleMapData (List<StructureInstance<TypeMapModuleEntry>> entries)
194172
{
195-
SymbolLabel = symbolLabel;
196173
Entries = entries;
197174
}
198175
}
@@ -219,6 +196,8 @@ sealed class ConstructionState
219196
public Dictionary<string, TypeMapJava> JavaTypesByName;
220197
public List<StructureInstance<TypeMapJava>> JavaMap;
221198
public List<ModuleMapData> AllModulesData;
199+
public List<List<StructureInstance<TypeMapModuleEntry>>> AllModulesMaps;
200+
public List<List<StructureInstance<TypeMapModuleEntry>>> AllModulesDuplicates;
222201
public LlvmIrStringBlob AssemblyNamesBlob;
223202
public LlvmIrStringBlob JavaTypeNamesBlob;
224203
public LlvmIrStringBlob ManagedTypeNamesBlob;
@@ -289,13 +268,25 @@ protected override void Construct (LlvmIrModule module)
289268
java_to_managed_hashes.WriteOptions &= ~LlvmIrVariableWriteOptions.ArrayWriteIndexComments;
290269
module.Add (java_to_managed_hashes);
291270

292-
foreach (ModuleMapData mmd in cs.AllModulesData) {
293-
var mmdVar = new LlvmIrGlobalVariable (mmd.Entries, mmd.SymbolLabel, LlvmIrVariableOptions.LocalConstant) {
294-
BeforeWriteCallback = SortEntriesAndUpdateJavaIndexes,
295-
BeforeWriteCallbackCallerState = cs,
296-
};
297-
module.Add (mmdVar);
298-
}
271+
// foreach (ModuleMapData mmd in cs.AllModulesData) {
272+
// var mmdVar = new LlvmIrGlobalVariable (mmd.Entries, mmd.SymbolLabel, LlvmIrVariableOptions.LocalConstant) {
273+
// BeforeWriteCallback = SortEntriesAndUpdateJavaIndexes,
274+
// BeforeWriteCallbackCallerState = cs,
275+
// };
276+
// module.Add (mmdVar);
277+
// }
278+
279+
var modulesMapData = new LlvmIrGlobalVariable (cs.AllModulesMaps, "modules_map_data", LlvmIrVariableOptions.GlobalConstant) {
280+
BeforeWriteCallback = SortEntriesAndUpdateJavaIndexes,
281+
BeforeWriteCallbackCallerState = cs,
282+
};
283+
module.Add (modulesMapData);
284+
285+
var modulesDuplicatesData = new LlvmIrGlobalVariable (cs.AllModulesMaps, "modules_duplicates_data", LlvmIrVariableOptions.GlobalConstant) {
286+
BeforeWriteCallback = SortEntriesAndUpdateJavaIndexes,
287+
BeforeWriteCallbackCallerState = cs,
288+
};
289+
module.Add (modulesMapData);
299290

300291
module.AddGlobalVariable ("java_to_managed_map", cs.JavaMap, LlvmIrVariableOptions.GlobalConstant, " Java to managed map");
301292
module.AddGlobalVariable ("java_type_names", cs.JavaTypeNamesBlob, LlvmIrVariableOptions.GlobalConstant, " Java type names");
@@ -433,21 +424,17 @@ void InitMapModules (ConstructionState cs)
433424

434425
cs.MapModules = new List<StructureInstance<TypeMapModule>> ();
435426
cs.AssemblyNamesBlob = new ();
436-
foreach (TypeMapGenerator.ModuleReleaseData data in mappingData.Modules) {
437-
string mapName = $"module{moduleCounter++}_managed_to_java";
438-
string duplicateMapName;
439-
440-
if (data.DuplicateTypes.Count == 0) {
441-
duplicateMapName = String.Empty;
442-
} else {
443-
duplicateMapName = $"{mapName}_duplicates";
444-
}
427+
cs.AllModulesMaps = new ();
428+
cs.AllModulesDuplicates = new ();
445429

430+
uint map_start_index = 0;
431+
uint duplicates_start_index = 0;
432+
foreach (TypeMapGenerator.ModuleReleaseData data in mappingData.Modules) {
433+
bool haveDuplicates = data.DuplicateTypes.Count > 0;
446434
(int assemblyNameIndex, int assemblyNameLength) = cs.AssemblyNamesBlob.Add (data.AssemblyName);
435+
447436
var map_module = new TypeMapModule {
448437
MVID = data.Mvid,
449-
MapSymbolName = mapName,
450-
DuplicateMapSymbolName = duplicateMapName.Length == 0 ? null : duplicateMapName,
451438
Data = data,
452439
AssemblyName = data.AssemblyName,
453440

@@ -456,8 +443,13 @@ void InitMapModules (ConstructionState cs)
456443
duplicate_count = (uint)data.DuplicateTypes.Count,
457444
assembly_name_index = (uint)assemblyNameIndex,
458445
assembly_name_length = (uint)assemblyNameLength,
446+
map_index = map_start_index,
447+
duplicate_map_index = haveDuplicates ? duplicates_start_index : 0,
459448
};
460449

450+
map_start_index += map_module.entry_count;
451+
duplicates_start_index += map_module.duplicate_count;
452+
461453
cs.MapModules.Add (new StructureInstance<TypeMapModule> (typeMapModuleStructureInfo, map_module));
462454
}
463455
}
@@ -469,14 +461,15 @@ void MapStructures (LlvmIrModule module)
469461
typeMapModuleEntryStructureInfo = module.MapStructure<TypeMapModuleEntry> ();
470462
}
471463

472-
void PrepareMapModuleData (string moduleDataSymbolLabel, IEnumerable<TypeMapGenerator.TypeMapReleaseEntry> moduleEntries, ConstructionState cs)
464+
void PrepareMapModuleData (IEnumerable<TypeMapGenerator.TypeMapReleaseEntry> moduleEntries, List<List<StructureInstance<TypeMapModuleEntry>>> destCollection, string sectionComment, ConstructionState cs)
473465
{
474466
var mapModuleEntries = new List<StructureInstance<TypeMapModuleEntry>> ();
475467
foreach (TypeMapGenerator.TypeMapReleaseEntry entry in moduleEntries) {
476468
if (!cs.JavaTypesByName.TryGetValue (entry.JavaName, out TypeMapJava javaType)) {
477469
throw new InvalidOperationException ($"Internal error: Java type '{entry.JavaName}' not found in cache");
478470
}
479471

472+
mapModuleEntries.Add (new StructureInstance<TypeMapModuleEntry> (typeMapModuleEntryStructureInfo, sectionComment));
480473
var map_entry = new TypeMapModuleEntry {
481474
JavaTypeMapEntry = javaType,
482475
ManagedTypeName = entry.ManagedTypeName,
@@ -487,19 +480,27 @@ void PrepareMapModuleData (string moduleDataSymbolLabel, IEnumerable<TypeMapGene
487480
};
488481
mapModuleEntries.Add (new StructureInstance<TypeMapModuleEntry> (typeMapModuleEntryStructureInfo, map_entry));
489482
}
490-
491-
// mapModuleEntries.Sort ((StructureInstance<TypeMapModuleEntry> a, StructureInstance<TypeMapModuleEntry> b) => a.Instance.type_token_id.CompareTo (b.Instance.type_token_id));
492-
cs.AllModulesData.Add (new ModuleMapData (moduleDataSymbolLabel, mapModuleEntries));
483+
destCollection.Add (mapModuleEntries);
493484
}
494485

495486
void PrepareModules (ConstructionState cs)
496487
{
497488
cs.AllModulesData = new List<ModuleMapData> ();
498489
foreach (StructureInstance<TypeMapModule> moduleInstance in cs.MapModules) {
499490
TypeMapModule module = moduleInstance.Instance;
500-
PrepareMapModuleData (module.MapSymbolName, module.Data.Types, cs);
491+
PrepareMapModuleData (
492+
module.Data.Types,
493+
cs.AllModulesMaps,
494+
$"Module: {module.AssemblyName}; MVID: {module.MVID}; number of entries: {module.Data.Types.Length}",
495+
cs
496+
);
501497
if (module.Data.DuplicateTypes.Count > 0) {
502-
PrepareMapModuleData (module.DuplicateMapSymbolName, module.Data.DuplicateTypes, cs);
498+
PrepareMapModuleData (
499+
module.Data.DuplicateTypes,
500+
cs.AllModulesDuplicates,
501+
$"Module: {module.AssemblyName}; MVID: {module.MVID}; number of entries: {module.Data.DuplicateTypes.Count}",
502+
cs
503+
);
503504
}
504505
}
505506
}

0 commit comments

Comments
 (0)