Skip to content

Commit

Permalink
Reformat WasmAppBuilder to conform to the coding conventions. NFC. (d…
Browse files Browse the repository at this point in the history
  • Loading branch information
vargaz authored May 30, 2020
1 parent 2ef008e commit b0463a4
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 108 deletions.
118 changes: 66 additions & 52 deletions tools-local/tasks/mobile.tasks/WasmAppBuilder/PInvokeTableGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,81 +24,93 @@ public class PInvokeTableGenerator : Task
[Required]
public string? OutputPath { get; set; }

public override bool Execute () {
GenPInvokeTable (Modules!.Select (item => item.ItemSpec).ToArray (), Assemblies!.Select (item => item.ItemSpec).ToArray ());
public override bool Execute()
{
GenPInvokeTable(Modules!.Select(item => item.ItemSpec).ToArray(), Assemblies!.Select(item => item.ItemSpec).ToArray());
return true;
}

void GenPInvokeTable (string[] pinvokeModules, string[] assemblies) {
private void GenPInvokeTable(string[] pinvokeModules, string[] assemblies)
{
var modules = new Dictionary<string, string> ();
foreach (var module in pinvokeModules)
modules [module] = module;

var pinvokes = new List<PInvoke> ();
var pinvokes = new List<PInvoke>();

var resolver = new PathAssemblyResolver (assemblies);
var mlc = new MetadataLoadContext (resolver, "System.Private.CoreLib");
foreach (var aname in assemblies) {
var a = mlc.LoadFromAssemblyPath (aname);
foreach (var type in a.GetTypes ())
CollectPInvokes (pinvokes, type);
var resolver = new PathAssemblyResolver(assemblies);
var mlc = new MetadataLoadContext(resolver, "System.Private.CoreLib");
foreach (var aname in assemblies)
{
var a = mlc.LoadFromAssemblyPath(aname);
foreach (var type in a.GetTypes())
CollectPInvokes(pinvokes, type);
}

Log.LogMessage (MessageImportance.Normal, $"Generating pinvoke table to '{OutputPath}'.");
Log.LogMessage(MessageImportance.Normal, $"Generating pinvoke table to '{OutputPath}'.");

using (var w = File.CreateText (OutputPath!)) {
EmitPInvokeTable (w, modules, pinvokes);
using (var w = File.CreateText(OutputPath!))
{
EmitPInvokeTable(w, modules, pinvokes);
}
}

void CollectPInvokes (List<PInvoke> pinvokes, Type type) {
private void CollectPInvokes(List<PInvoke> pinvokes, Type type)
{
foreach (var method in type.GetMethods (BindingFlags.DeclaredOnly|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static|BindingFlags.Instance)) {
if ((method.Attributes & MethodAttributes.PinvokeImpl) == 0)
continue;
var dllimport = method.CustomAttributes.First (attr => attr.AttributeType.Name == "DllImportAttribute");
var module = (string)dllimport.ConstructorArguments [0].Value!;
var entrypoint = (string)dllimport.NamedArguments.First (arg => arg.MemberName == "EntryPoint").TypedValue.Value!;
pinvokes.Add (new PInvoke (entrypoint, module, method));
var dllimport = method.CustomAttributes.First(attr => attr.AttributeType.Name == "DllImportAttribute");
var module = (string)dllimport.ConstructorArguments[0].Value!;
var entrypoint = (string)dllimport.NamedArguments.First(arg => arg.MemberName == "EntryPoint").TypedValue.Value!;
pinvokes.Add(new PInvoke(entrypoint, module, method));
}
}

void EmitPInvokeTable (StreamWriter w, Dictionary<string, string> modules, List<PInvoke> pinvokes) {
w.WriteLine ("// GENERATED FILE, DO NOT MODIFY");
w.WriteLine ("typedef struct {");
w.WriteLine ("const char *name;");
w.WriteLine ("void *func;");
w.WriteLine ("} PinvokeImport;");
w.WriteLine ();

foreach (var pinvoke in pinvokes) {
if (modules.ContainsKey (pinvoke.Module))
w.WriteLine (GenPInvokeDecl (pinvoke));
private void EmitPInvokeTable(StreamWriter w, Dictionary<string, string> modules, List<PInvoke> pinvokes)
{
w.WriteLine("// GENERATED FILE, DO NOT MODIFY");
w.WriteLine("typedef struct {");
w.WriteLine("const char *name;");
w.WriteLine("void *func;");
w.WriteLine("} PinvokeImport;");
w.WriteLine();

foreach (var pinvoke in pinvokes)
{
if (modules.ContainsKey(pinvoke.Module))
w.WriteLine(GenPInvokeDecl(pinvoke));
}

foreach (var module in modules.Keys) {
string symbol = module.Replace (".", "_") + "_imports";
w.WriteLine ("static PinvokeImport " + symbol + " [] = {");
foreach (var pinvoke in pinvokes) {
foreach (var module in modules.Keys)
{
string symbol = module.Replace(".", "_") + "_imports";
w.WriteLine("static PinvokeImport " + symbol + " [] = {");
foreach (var pinvoke in pinvokes)
{
if (pinvoke.Module == module)
w.WriteLine ("{\"" + pinvoke.EntryPoint + "\", " + pinvoke.EntryPoint + "},");
w.WriteLine("{\"" + pinvoke.EntryPoint + "\", " + pinvoke.EntryPoint + "},");
}
w.WriteLine ("{NULL, NULL}");
w.WriteLine ("};");
}
w.Write ("static void *pinvoke_tables[] = { ");
foreach (var module in modules.Keys) {
string symbol = module.Replace (".", "_") + "_imports";
w.Write (symbol + ",");
foreach (var module in modules.Keys)
{
string symbol = module.Replace(".", "_") + "_imports";
w.Write(symbol + ",");
}
w.WriteLine ("};");
w.WriteLine("};");
w.Write ("static char *pinvoke_names[] = { ");
foreach (var module in modules.Keys) {
w.Write ("\"" + module + "\"" + ",");
foreach (var module in modules.Keys)
{
w.Write("\"" + module + "\"" + ",");
}
w.WriteLine ("};");
w.WriteLine("};");
}

string MapType (Type t) {
private string MapType (Type t)
{
string name = t.Name;
if (name == "Void")
return "void";
Expand All @@ -114,28 +126,30 @@ string MapType (Type t) {
return "int";
}

string GenPInvokeDecl (PInvoke pinvoke) {
var sb = new StringBuilder ();
private string GenPInvokeDecl(PInvoke pinvoke)
{
var sb = new StringBuilder();
var method = pinvoke.Method;
sb.Append (MapType (method.ReturnType));
sb.Append ($" {pinvoke.EntryPoint} (");
sb.Append(MapType (method.ReturnType));
sb.Append($" {pinvoke.EntryPoint} (");
int pindex = 0;
var pars = method.GetParameters ();
foreach (var p in pars) {
if (pindex > 0)
sb.Append (",");
sb.Append (MapType (pars [pindex].ParameterType));
sb.Append(",");
sb.Append(MapType (pars[pindex].ParameterType));
pindex ++;
}
sb.Append (");");
return sb.ToString ();
sb.Append(");");
return sb.ToString();
}
}

class PInvoke
{
public PInvoke (string entry_point, string module, MethodInfo method) {
EntryPoint = entry_point;
public PInvoke(string entryPoint, string module, MethodInfo method)
{
EntryPoint = entryPoint;
Module = module;
Method = method;
}
Expand Down
125 changes: 69 additions & 56 deletions tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,97 +31,110 @@ public class WasmAppBuilder : Task
public ITaskItem[]? ExtraAssemblies { get; set; }
public ITaskItem[]? ExtraFiles { get; set; }

Dictionary<string, Assembly>? Assemblies;
Resolver? Resolver;
Dictionary<string, Assembly>? _assemblies;
Resolver? _resolver;

public override bool Execute () {
if (!File.Exists (MainAssembly))
throw new ArgumentException ($"File MainAssembly='{MainAssembly}' doesn't exist.");
if (!File.Exists (MainJS))
throw new ArgumentException ($"File MainJS='{MainJS}' doesn't exist.");
public override bool Execute ()
{
if (!File.Exists(MainAssembly))
throw new ArgumentException($"File MainAssembly='{MainAssembly}' doesn't exist.");
if (!File.Exists(MainJS))
throw new ArgumentException($"File MainJS='{MainJS}' doesn't exist.");

var paths = new List<string> ();
Assemblies = new Dictionary<string, Assembly> ();
var paths = new List<string>();
_assemblies = new Dictionary<string, Assembly>();

// Collect and load assemblies used by the app
foreach (var v in AssemblySearchPaths!) {
foreach (var v in AssemblySearchPaths!)
{
var dir = v.ItemSpec;
if (!Directory.Exists (dir))
throw new ArgumentException ($"Directory '{dir}' doesn't exist or not a directory.");
paths.Add (dir);
if (!Directory.Exists(dir))
throw new ArgumentException($"Directory '{dir}' doesn't exist or not a directory.");
paths.Add(dir);
}
Resolver = new Resolver (paths);
var mlc = new MetadataLoadContext (Resolver, "System.Private.CoreLib");
_resolver = new Resolver(paths);
var mlc = new MetadataLoadContext(_resolver, "System.Private.CoreLib");

var mainAssembly = mlc.LoadFromAssemblyPath (MainAssembly);
Add (mlc, mainAssembly);

if (ExtraAssemblies != null) {
foreach (var item in ExtraAssemblies) {
var refAssembly = mlc.LoadFromAssemblyPath (item.ItemSpec);
Add (mlc, refAssembly);
Add(mlc, mainAssembly);

if (ExtraAssemblies != null)
{
foreach (var item in ExtraAssemblies)
{
var refAssembly = mlc.LoadFromAssemblyPath(item.ItemSpec);
Add(mlc, refAssembly);
}
}

// Create app
Directory.CreateDirectory (AppDir!);
Directory.CreateDirectory (Path.Join (AppDir, "managed"));
foreach (var assembly in Assemblies!.Values)
File.Copy (assembly.Location, Path.Join (AppDir, "managed", Path.GetFileName (assembly.Location)), true);
foreach (var f in new string [] { "dotnet.wasm", "dotnet.js" })
File.Copy (Path.Join (RuntimePackDir, "native", "wasm", "runtimes", "release", f), Path.Join (AppDir, f), true);
File.Copy (MainJS!, Path.Join (AppDir, "runtime.js"), true);

if (ExtraFiles != null) {
Directory.CreateDirectory(AppDir!);
Directory.CreateDirectory(Path.Join(AppDir, "managed"));
foreach (var assembly in _assemblies!.Values)
File.Copy(assembly.Location, Path.Join(AppDir, "managed", Path.GetFileName(assembly.Location)), true);
foreach (var f in new string[] { "dotnet.wasm", "dotnet.js" })
File.Copy(Path.Join (RuntimePackDir, "native", "wasm", "runtimes", "release", f), Path.Join(AppDir, f), true);
File.Copy(MainJS!, Path.Join(AppDir, "runtime.js"), true);

if (ExtraFiles != null)
{
foreach (var item in ExtraFiles)
File.Copy (item.ItemSpec, Path.Join (AppDir, Path.GetFileName (item.ItemSpec)), true);
File.Copy(item.ItemSpec, Path.Join(AppDir, Path.GetFileName(item.ItemSpec)), true);
}

using (var sw = File.CreateText (Path.Join (AppDir, "mono-config.js"))) {
sw.WriteLine ("config = {");
sw.WriteLine ("\tvfs_prefix: \"managed\",");
sw.WriteLine ("\tdeploy_prefix: \"managed\",");
sw.WriteLine ("\tenable_debugging: 0,");
sw.WriteLine ("\tfile_list: [");
foreach (var assembly in Assemblies.Values) {
sw.Write ("\"" + Path.GetFileName (assembly.Location) + "\"");
sw.Write (", ");
using (var sw = File.CreateText(Path.Join(AppDir, "mono-config.js")))
{
sw.WriteLine("config = {");
sw.WriteLine("\tvfs_prefix: \"managed\",");
sw.WriteLine("\tdeploy_prefix: \"managed\",");
sw.WriteLine("\tenable_debugging: 0,");
sw.WriteLine("\tfile_list: [");
foreach (var assembly in _assemblies.Values)
{
sw.Write("\"" + Path.GetFileName(assembly.Location) + "\"");
sw.Write(", ");
}
sw.WriteLine ("],");
sw.WriteLine ("}");
}

using (var sw = File.CreateText (Path.Join (AppDir, "run-v8.sh"))) {
sw.WriteLine ("v8 --expose_wasm runtime.js -- --enable-gc --run " + Path.GetFileName (MainAssembly) + " $*");
using (var sw = File.CreateText(Path.Join(AppDir, "run-v8.sh")))
{
sw.WriteLine("v8 --expose_wasm runtime.js -- --enable-gc --run " + Path.GetFileName(MainAssembly) + " $*");
}

return true;
}

void Add (MetadataLoadContext mlc, Assembly assembly) {
Assemblies! [assembly.GetName ().Name!] = assembly;
foreach (var aname in assembly.GetReferencedAssemblies ()) {
var refAssembly = mlc.LoadFromAssemblyName (aname);
Add (mlc, refAssembly);
private void Add(MetadataLoadContext mlc, Assembly assembly)
{
_assemblies![assembly.GetName().Name!] = assembly;
foreach (var aname in assembly.GetReferencedAssemblies())
{
var refAssembly = mlc.LoadFromAssemblyName(aname);
Add(mlc, refAssembly);
}
}
}

class Resolver : MetadataAssemblyResolver
{
List<String> SearchPaths;
List<String> _searchPaths;

public Resolver (List<string> searchPaths) {
this.SearchPaths = searchPaths;
public Resolver(List<string> searchPaths)
{
_searchPaths = searchPaths;
}

public override Assembly? Resolve (MetadataLoadContext context, AssemblyName assemblyName) {
public override Assembly? Resolve(MetadataLoadContext context, AssemblyName assemblyName)
{
var name = assemblyName.Name;
foreach (var dir in SearchPaths) {
var path = Path.Combine (dir, name + ".dll");
if (File.Exists (path)) {
Console.WriteLine (path);
return context.LoadFromAssemblyPath (path);
foreach (var dir in _searchPaths)
{
var path = Path.Combine(dir, name + ".dll");
if (File.Exists(path))
{
return context.LoadFromAssemblyPath(path);
}
}
return null;
Expand Down

0 comments on commit b0463a4

Please sign in to comment.