[mono][wasm] marshal-ilgen is dropped when not required#86035
[mono][wasm] marshal-ilgen is dropped when not required#86035jandupej merged 33 commits intodotnet:mainfrom
Conversation
lambdageek
left a comment
There was a problem hiding this comment.
I wonder if the stub emit method can assert in a few places.
lambdageek
left a comment
There was a problem hiding this comment.
native code changes lgtm. I have a couple of suggestions for the build task - the biggest one being whether we can use the type system from NativeAOT instead of building our own signature provider. if we use our own, then I think we need some comments to explain what is going on. It is not obvious.
Also check the weird ECMA edge-case of "generic" enum types that arise from nested types.
src/tasks/MonoTargetsTasks/MarshalingPInvokeScanner/MarshalingPInvokeScanner.cs
Outdated
Show resolved
Hide resolved
src/tasks/MonoTargetsTasks/MarshalingPInvokeScanner/MarshalingPInvokeScanner.cs
Outdated
Show resolved
Hide resolved
src/tasks/MonoTargetsTasks/MarshalingPInvokeScanner/MarshalingPInvokeScanner.cs
Outdated
Show resolved
Hide resolved
src/tasks/MonoTargetsTasks/MarshalingPInvokeScanner/MarshalingPInvokeScanner.cs
Outdated
Show resolved
Hide resolved
|
|
||
| <UsingTask TaskName="Microsoft.WebAssembly.Build.Tasks.ManagedToNativeGenerator" AssemblyFile="$(WasmAppBuilderTasksAssemblyPath)" /> | ||
| <UsingTask TaskName="Microsoft.WebAssembly.Build.Tasks.EmccCompile" AssemblyFile="$(WasmAppBuilderTasksAssemblyPath)" /> | ||
| <UsingTask TaskName="MarshalingPInvokeScanner" AssemblyFile="$(MonoTargetsTasksAssemblyPath)" /> |
src/tasks/Common/PInvokeCollector.cs
Outdated
|
|
||
|
|
|
|
||
|
|
||
| } | ||
|
|
|
|
||
|
|
||
| #pragma warning disable CS0649 | ||
| internal sealed class PInvokeCallback |
There was a problem hiding this comment.
This could be a record like:
internal sealed record PInvokeCallback(MethodInfo method, string? EntryName = null);
src/tasks/Common/PInvokeCollector.cs
Outdated
|
|
||
|
|
||
|
|
src/tasks/Common/PInvokeCollector.cs
Outdated
|
|
||
| internal sealed class PInvokeCollector { | ||
| private readonly Dictionary<Assembly, bool> _assemblyDisableRuntimeMarshallingAttributeCache = new(); | ||
| private TaskLoggingHelper Log { get; set; } |
There was a problem hiding this comment.
| private TaskLoggingHelper Log { get; set; } | |
| private readonly TaskLoggingHelper Log { get; init; } |
| if(mdtReader.GetString(td.Name) == "DisableRuntimeMarshallingAttribute") | ||
| return false; | ||
| } | ||
| catch(InvalidCastException) |
There was a problem hiding this comment.
Which part can throw this exception?
| TypeDefinitionHandle tdh = md.GetDeclaringType(); | ||
| TypeDefinition td = mdtReader.GetTypeDefinition(tdh); | ||
|
|
||
| if(mdtReader.GetString(td.Name) == "DisableRuntimeMarshallingAttribute") |
| SignatureDecoder<Compatibility, object> decoder = new SignatureDecoder<Compatibility, object>( | ||
| mmtcp, mdtReader, null!); |
There was a problem hiding this comment.
| SignatureDecoder<Compatibility, object> decoder = new SignatureDecoder<Compatibility, object>( | |
| mmtcp, mdtReader, null!); | |
| SignatureDecoder<Compatibility, object> decoder = new(mmtcp, mdtReader, null!); |
| MethodSignature<Compatibility> sgn = decoder.DecodeMethodSignature(ref sgnBlobReader); | ||
| if(sgn.ReturnType == Compatibility.Incompatible || sgn.ParameterTypes.Any(p => p == Compatibility.Incompatible)) | ||
| { | ||
| Log.LogMessage(MessageImportance.Low, string.Format("Assebly {0} requires marhsal-ilgen for method {1}.{2}:{3} (first pass).", |
There was a problem hiding this comment.
| Log.LogMessage(MessageImportance.Low, string.Format("Assebly {0} requires marhsal-ilgen for method {1}.{2}:{3} (first pass).", | |
| Log.LogMessage(MessageImportance.Low, string.Format("Assembly {0} requires marhsal-ilgen for method {1}.{2}:{3} (first pass).", |
| var pinvokes = new List<PInvoke>(); | ||
| var callbacks = new List<PInvokeCallback>(); | ||
|
|
||
| PInvokeCollector pinvokeCollector = new PInvokeCollector(Log); |
There was a problem hiding this comment.
| PInvokeCollector pinvokeCollector = new PInvokeCollector(Log); | |
| PInvokeCollector pinvokeCollector = new(Log); |
A new analyzer
MarshlingPInvokeScanneris added, that scans all assemblies for constructs incompatible with the lightweight marshaller. This is essentially every P/Invoke that uses a nonblittable type as argument or returns it. The analyzer usesSystem.Reflection.Metadatato remain compatible with .NET Framework.Additionally, the wasm toolchain uses this analyzer to decide whether
marshal-ilgenis needed. If it is not, the full marshaller is dropped in favor of the lightweight one.EDIT: The reduction in
dotnet.native.wasmis approx. 74 KB whenmarshal-ilgenis dropped in favor of its stub.