-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[mono][wasm] marshal-ilgen is dropped when not required #86035
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if the stub emit method can assert in a few places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
@@ -3,9 +3,11 @@ | |||
|
|||
<UsingTask TaskName="Microsoft.WebAssembly.Build.Tasks.ManagedToNativeGenerator" AssemblyFile="$(WasmAppBuilderTasksAssemblyPath)" /> | |||
<UsingTask TaskName="Microsoft.WebAssembly.Build.Tasks.EmccCompile" AssemblyFile="$(WasmAppBuilderTasksAssemblyPath)" /> | |||
<UsingTask TaskName="MarshalingPInvokeScanner" AssemblyFile="$(MonoTargetsTasksAssemblyPath)" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add namespace for the task
src/tasks/Common/PInvokeCollector.cs
Outdated
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/tasks/Common/PInvokeCollector.cs
Outdated
|
||
|
||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/tasks/Common/PInvokeCollector.cs
Outdated
|
||
|
||
#pragma warning disable CS0649 | ||
internal sealed class PInvokeCallback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be a record like:
internal sealed record PInvokeCallback(MethodInfo method, string? EntryName = null);
src/tasks/Common/PInvokeCollector.cs
Outdated
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which part can throw this exception?
TypeDefinitionHandle tdh = md.GetDeclaringType(); | ||
TypeDefinition td = mdtReader.GetTypeDefinition(tdh); | ||
|
||
if(mdtReader.GetString(td.Name) == "DisableRuntimeMarshallingAttribute") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.. and check namespace
SignatureDecoder<Compatibility, object> decoder = new SignatureDecoder<Compatibility, object>( | ||
mmtcp, mdtReader, null!); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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).", |
@@ -35,6 +35,8 @@ public IEnumerable<string> Generate(string[] pinvokeModules, IEnumerable<string> | |||
var pinvokes = new List<PInvoke>(); | |||
var callbacks = new List<PInvokeCallback>(); | |||
|
|||
PInvokeCollector pinvokeCollector = new PInvokeCollector(Log); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PInvokeCollector pinvokeCollector = new PInvokeCollector(Log); | |
PInvokeCollector pinvokeCollector = new(Log); |
A new analyzer
MarshlingPInvokeScanner
is 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.Metadata
to remain compatible with .NET Framework.Additionally, the wasm toolchain uses this analyzer to decide whether
marshal-ilgen
is needed. If it is not, the full marshaller is dropped in favor of the lightweight one.EDIT: The reduction in
dotnet.native.wasm
is approx. 74 KB whenmarshal-ilgen
is dropped in favor of its stub.