Skip to content

Commit

Permalink
[WIP] marshal methods & IntPtr.Size
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanpeppers committed Jun 28, 2023
1 parent efa14e2 commit d481a15
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using Java.Interop.Tools.Cecil;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Linker;
using Mono.Tuner;
using MonoDroid.Tuner;
using NUnit.Framework;
using Xamarin.ProjectTools;
Expand Down Expand Up @@ -525,13 +528,24 @@ public void DoNotErrorOnPerArchJavaTypeDuplicates ()
lib.Sources.Add (new BuildItem.Source ("Library1.cs") {
TextContent = () => @"
namespace Lib1;
public class Library1 : Java.Lang.Object {
public class Library1 : Com.Example.Androidlib.MyRunner {
private static bool Is64Bits = IntPtr.Size >= 8;
public static bool Is64 () {
return Is64Bits;
}
public override void Run () => Console.WriteLine (Is64Bits);
}",
});
lib.Sources.Add (new BuildItem ("AndroidJavaSource", "MyRunner.java") {
Encoding = new UTF8Encoding (encoderShouldEmitUTF8Identifier: false),
TextContent = () => @"
package com.example.androidlib;
public abstract class MyRunner {
public abstract void run();
}"
});
var proj = new XamarinAndroidApplicationProject { IsRelease = true, ProjectName = "App1" };
proj.References.Add(new BuildItem.ProjectReference (Path.Combine ("..", "Lib1", "Lib1.csproj"), "Lib1"));
Expand All @@ -545,6 +559,41 @@ public static bool Is64 () {
using var b = CreateApkBuilder (Path.Combine (path, "App1"));
Assert.IsTrue (lb.Build (lib), "build should have succeeded.");
Assert.IsTrue (b.Build (proj), "build should have succeeded.");

var intermediate = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath);
var dll = $"{lib.ProjectName}.dll";
Assert64Bit ("android-arm", expected64: false);
Assert64Bit ("android-arm64", expected64: true);
Assert64Bit ("android-x86", expected64: false);
Assert64Bit ("android-x64", expected64: true);

void Assert64Bit(string rid, bool expected64)
{
var assembly = AssemblyDefinition.ReadAssembly (Path.Combine (intermediate, rid, "linked", "shrunk", dll));
var type = assembly.MainModule.FindType ("Lib1.Library1");
Assert.NotNull (type, "Should find Lib1.Library1!");
var cctor = type.GetTypeConstructor ();
Assert.NotNull (type, "Should find Lib1.Library1.cctor!");
Assert.AreNotEqual (0, cctor.Body.Instructions.Count);

/*
* IL snippet
* .method private hidebysig specialname rtspecialname static
* void .cctor () cil managed
* {
* // Is64Bits = 4 >= 8;
* IL_0000: ldc.i4 4
* IL_0005: ldc.i4.8
* ...
*/
var instruction = cctor.Body.Instructions [0];
Assert.AreEqual (OpCodes.Ldc_I4, instruction.OpCode);
if (expected64) {
Assert.AreEqual (8, instruction.Operand, $"Expected 64-bit: {expected64}");
} else {
Assert.AreEqual (4, instruction.Operand, $"Expected 64-bit: {expected64}");
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,47 +114,37 @@ public void Rewrite (DirectoryAssemblyResolver resolver, List<string> targetAsse
}
}

var newAssemblyPaths = new List<string> ();
var newAssemblyPaths = new List<ValueTuple<string, string>> ();
foreach (AssemblyDefinition asm in uniqueAssemblies) {
foreach (string path in GetAssemblyPaths (asm)) {
foreach (string original in GetAssemblyPaths (asm)) {
var writerParams = new WriterParameters {
WriteSymbols = File.Exists (Path.ChangeExtension (path, ".pdb")),
WriteSymbols = File.Exists (Path.ChangeExtension (original, ".pdb")),
};

string directory = Path.Combine (Path.GetDirectoryName (path), "new");
string directory = Path.Combine (Path.GetDirectoryName (original), "new");
Directory.CreateDirectory (directory);
string output = Path.Combine (directory, Path.GetFileName (path));
log.LogDebugMessage ($"Writing new version of assembly: {output}");
string temp = Path.Combine (directory, Path.GetFileName (original));
log.LogDebugMessage ($"Writing new version of assembly: {temp}");

// TODO: this should be used eventually, but it requires that all the types are reloaded from the assemblies before typemaps are generated
// since Cecil doesn't update the MVID in the already loaded types
//asm.MainModule.Mvid = Guid.NewGuid ();
asm.Write (output, writerParams);
newAssemblyPaths.Add (output);
asm.Write (temp, writerParams);
newAssemblyPaths.Add ((original, temp));
}
}

// Replace old versions of the assemblies only after we've finished rewriting without issues, otherwise leave the new
// versions around.
foreach (string path in newAssemblyPaths) {
string? pdb = null;

string source = Path.ChangeExtension (path, ".pdb");
if (File.Exists (source)) {
pdb = source;
}

foreach (string targetPath in targetAssemblyPaths) {
string target = Path.Combine (targetPath, Path.GetFileName (path));
CopyFile (path, target);

if (!String.IsNullOrEmpty (pdb)) {
CopyFile (pdb, Path.ChangeExtension (target, ".pdb"));
}
foreach ((string original, string temp) in newAssemblyPaths) {
CopyFile (temp, original);
RemoveFile (temp);

var pdb = Path.ChangeExtension (temp, ".pdb");
if (File.Exists(pdb)) {
CopyFile (pdb, Path.ChangeExtension (original, ".pdb"));
RemoveFile (pdb);
}

RemoveFile (path);
RemoveFile (pdb);
}

void CopyFile (string source, string target)
Expand Down

0 comments on commit d481a15

Please sign in to comment.