Skip to content

Commit 20088b4

Browse files
committed
Implement marshal methods LLVM IR executable code generator.
The point of this commit is only to generate code and make sure it's valid as far as compiling and linking are concerned. The code has not been tested at run time as not all the infrastructure on the Xamarin.Android side is implemented yet. This is on purpose, to keep PRs smaller. The majority of this PR introduces various classes, enums and structures related to code generation. Support for various LLVM IR instructions is limited only to those we actually use and only to elements of those constructions that we use. As such, it's not a general purpose code generator which allows us to make some assumptions and take some shortcuts (without compromising correctness and validity of the generated code) Portions of the PR (the native type handling system) are to be treated as proof-of-concept as they are not as optimized (design wise) as they should be. The reason for this limitation is that it requires modifying the previous LLVM IR data generation code and it would contribute to this PR's already substantial size. The next PR in the series will take care of that rewrite as well as it will focus on implementing the runtime side of marshal methods, making it possible to actually run applications which use marshal methods. What this PR implements is the following: * LLVM IR * function and instruction attributes * function parameter (declaration/definition) and argument (runtime) handling * function variable (including parameters) handling, including unnamed local variables * support for native function signatures and pointers to functions * The ret, store, load, icmp, br, call and phi instructions * Marshal method generator * managed to JNI signature and symbol name translations
1 parent 938b2cb commit 20088b4

28 files changed

+2468
-54
lines changed

src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ void Run (DirectoryAssemblyResolver res)
237237
string managedKey = type.FullName.Replace ('/', '.');
238238
string javaKey = JavaNativeTypeManager.ToJniName (type, cache).Replace ('/', '.');
239239

240+
Console.WriteLine ($"##G2: {type.FullName} -> {javaKey}");
240241
acw_map.Write (type.GetPartialAssemblyQualifiedName (cache));
241242
acw_map.Write (';');
242243
acw_map.Write (javaKey);
@@ -384,6 +385,7 @@ bool CreateJavaSources (IEnumerable<TypeDefinition> javaTypes, TypeDefinitionCac
384385

385386
bool ok = true;
386387
foreach (var t in javaTypes) {
388+
Console.WriteLine ($"##G0: JCW for {t.FullName}");
387389
if (t.IsInterface) {
388390
// Interfaces are in typemap but they shouldn't have JCW generated for them
389391
continue;

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ class Arm32LlvmIrGenerator : LlvmIrGenerator
1616
public override int PointerSize => 4;
1717
protected override string Triple => "armv7-unknown-linux-android"; // NDK appends API level, we don't need that
1818

19+
static readonly LlvmFunctionAttributeSet commonAttributes = new LlvmFunctionAttributeSet {
20+
new FramePointerFunctionAttribute ("all"),
21+
new TargetCpuFunctionAttribute ("generic"),
22+
new TargetFeaturesFunctionAttribute ("+armv7-a,+d32,+dsp,+fp64,+neon,+thumb-mode,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-aes,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-sha2,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"),
23+
};
24+
1925
public Arm32LlvmIrGenerator (AndroidTargetArch arch, StreamWriter output, string fileName)
2026
: base (arch, output, fileName)
2127
{}
@@ -25,5 +31,13 @@ protected override void AddModuleFlagsMetadata (List<LlvmIrMetadataItem> flagsFi
2531
base.AddModuleFlagsMetadata (flagsFields);
2632
flagsFields.Add (MetadataManager.AddNumbered (LlvmIrModuleMergeBehavior.Error, "min_enum_size", 4));
2733
}
34+
35+
protected override void InitFunctionAttributes ()
36+
{
37+
base.InitFunctionAttributes ();
38+
39+
FunctionAttributes[FunctionAttributesXamarinAppInit].Add (commonAttributes);
40+
FunctionAttributes[FunctionAttributesJniMethods].Add (commonAttributes);
41+
}
2842
}
2943
}

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ class Arm64LlvmIrGenerator : LlvmIrGenerator
1616
public override int PointerSize => 8;
1717
protected override string Triple => "aarch64-unknown-linux-android"; // NDK appends API level, we don't need that
1818

19+
static readonly LlvmFunctionAttributeSet commonAttributes = new LlvmFunctionAttributeSet {
20+
new FramePointerFunctionAttribute ("non-leaf"),
21+
new TargetCpuFunctionAttribute ("generic"),
22+
new TargetFeaturesFunctionAttribute ("+neon,+outline-atomics"),
23+
};
24+
1925
public Arm64LlvmIrGenerator (AndroidTargetArch arch, StreamWriter output, string fileName)
2026
: base (arch, output, fileName)
2127
{}
@@ -29,5 +35,13 @@ protected override void AddModuleFlagsMetadata (List<LlvmIrMetadataItem> flagsFi
2935
flagsFields.Add (MetadataManager.AddNumbered (LlvmIrModuleMergeBehavior.Error, "sign-return-address-all", 0));
3036
flagsFields.Add (MetadataManager.AddNumbered (LlvmIrModuleMergeBehavior.Error, "sign-return-address-with-bkey", 0));
3137
}
38+
39+
protected override void InitFunctionAttributes ()
40+
{
41+
base.InitFunctionAttributes ();
42+
43+
FunctionAttributes[FunctionAttributesXamarinAppInit].Add (commonAttributes);
44+
FunctionAttributes[FunctionAttributesJniMethods].Add (commonAttributes);
45+
}
3246
}
3347
}

0 commit comments

Comments
 (0)