You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Unhandled exception. System.PlatformNotSupportedException: Dynamic code generation is not supported on this platform.
at System.Reflection.Emit.AssemblyBuilder.ThrowDynamicCodeNotSupported()
at System.Reflection.Emit.DynamicMethod.Init(String name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] signature, Type owner, Module m, Boolean skipVisibility, Boolean transparentMethod)
at System.Reflection.Emit.DynamicMethod..ctor(String name, Type returnType, Type[] parameterTypes)
at System.Dynamic.Utils.DelegateHelpers.CreateObjectArrayDelegateRefEmit(Type delegateType, Func`2 handler)
This was fixed with #80759. Linq.Expressions should still work, even though PublishAot=true. It just doesn't use Ref.Emit in that case, it falls back to the interpreter mode, like it will for the published app.
This was fixed with #80759. Linq.Expressions should still work, even though PublishAot=true. It just doesn't use Ref.Emit in that case, it falls back to the interpreter mode, like it will for the published app.
This is intentional so that people don't get unpleasant surprise after they debug their app, they're ready to publish, and it doesn't work.
What's the scenario where a working Ref.Emit would be needed during inner dev loop, but got broken on publish?
I was just using this specific case to illustrate that PublishAot has a functional impact on the code. The approach EF Core is using to add support for NativeAOT is to first run a portion of the app in JIT, perform all the dynamic operations that would be normally not supported by NativeAOT, then generate source code for the app that would be compatible with NativeAOT.
Currently it's possible to do this by removing PublishAot before running the EF tool, but this would be less than ideal experience once we ship 8.0
I was just using this specific case to illustrate that PublishAot has a functional impact on the code.
This is intentional, as @MichalStrehovsky says above. We want the app running during dotnet run and F5 to behave the same way as it will once publishing the app. There are other impacts besides not being able to use Ref.Emit, for example "Startup Hooks" are disabled, so is BinaryFormatter and "Built-in COM" support.
The approach EF Core is using to add support for NativeAOT is to first run a portion of the app in JIT
My understanding is that EF Core doesn't use Ref.Emit directly, but instead uses System.Linq.Expressions. If this is the case, Linq.Expressions will opt to not use Ref.Emit, but instead use an interpreted mode. So it will still work correctly with PublishAot in the .csproj. You just need to upgrade to a newer build.
My understanding is that EF Core doesn't use Ref.Emit directly, but instead uses System.Linq.Expressions. If this is the case, Linq.Expressions will opt to not use Ref.Emit, but instead use an interpreted mode.
Correct. As long as there are no other intentional functional differences than the ones mentioned above it should be fine.
You just need to upgrade to a newer build.
I still get it with SDK 8.0.100-preview.2.23108.9 and runtime 8.0.0-preview.2.23102.7
The approach EF Core is using to add support for NativeAOT is to first run a portion of the app in JIT, perform all the dynamic operations that would be normally not supported by NativeAOT, then generate source code for the app that would be compatible with NativeAOT.
How do you guarantee that the test execution of the app performed all operations that the app needs to perform dynamically?
How do you guarantee that the test execution of the app performed all operations that the app needs to perform dynamically?
Of course, we can't guarantee that. We discover the user's DbContext and the statically known LINQ queries. But we also plan to provide a hook that would allow the users to explicitly call the dynamic queries and we'll generate code for the exercised combinations. Truly dynamic models and queries won't be supported. We are investigating whether we can provide an analyzer that would find the unsupported queries to avoid trial and error. Also, if the user runs their tests with <PublishAot>true</PublishAot> we'll throw for anything unsupported.
When running on CoreCLR, this type/method doesn't exist. Is there a way to simulate what CreateObjectArrayDelegate does when running on CoreCLR?
We would need Ref.Emit on CoreCLR to emulate it, so it's better to not take this codepath and leave the existing Ref.Emit one since it's ref.emit either way. In Native AOT, this relies on the fact that the AOT compiler will generate extra thunks for each delegate type in the app to support this.
I understand it's a bit of a pickle because we don't want ref.emit to work. We might need some sort of backdoor ref-emit.
What I mean is that we would add a private API from CoreLib that we reflection-discover like the above CreateObjectArrayDelegate. It would set a threadstatic somewhere in CoreLib that would say "this thread now allows Ref.Emit" and e.g. return an IDisposable (that would set it back to ref emit not supported). Then whenever we're about to throw in CoreLib because someone attempted ref-emit, we would additionally check for this threadstatic.
I'm not a Runtime Expert, but in Xamarin the same problem exsists.
Because on iOS only Native Code is allowed (AOT). So to support Dynamic Code the (Mono) Interpreter is used as a FallBack to handle Reflection.Emit and other dynamic Code Patterns.
Project Property for that <UseInterpreter>true</UseInterpreter>
Activity
MichalStrehovsky commentedon Feb 8, 2023
This is intentional so that people don't get unpleasant surprise after they debug their app, they're ready to publish, and it doesn't work.
What's the scenario where a working Ref.Emit would be needed during inner dev loop, but got broken on publish?
Cc @eerhardt
eerhardt commentedon Feb 8, 2023
This was fixed with #80759. Linq.Expressions should still work, even though PublishAot=true. It just doesn't use Ref.Emit in that case, it falls back to the interpreter mode, like it will for the published app.
@AndriySvyryd - can you try a newer build?
AndriySvyryd commentedon Feb 8, 2023
I was just using this specific case to illustrate that
PublishAothas a functional impact on the code. The approach EF Core is using to add support for NativeAOT is to first run a portion of the app in JIT, perform all the dynamic operations that would be normally not supported by NativeAOT, then generate source code for the app that would be compatible with NativeAOT.Currently it's possible to do this by removing
PublishAotbefore running the EF tool, but this would be less than ideal experience once we ship 8.0eerhardt commentedon Feb 8, 2023
This is intentional, as @MichalStrehovsky says above. We want the app running during
dotnet runand F5 to behave the same way as it will once publishing the app. There are other impacts besides not being able to use Ref.Emit, for example "Startup Hooks" are disabled, so is BinaryFormatter and "Built-in COM" support.My understanding is that EF Core doesn't use Ref.Emit directly, but instead uses System.Linq.Expressions. If this is the case, Linq.Expressions will opt to not use Ref.Emit, but instead use an interpreted mode. So it will still work correctly with
PublishAotin the .csproj. You just need to upgrade to a newer build.AndriySvyryd commentedon Feb 9, 2023
Correct. As long as there are no other intentional functional differences than the ones mentioned above it should be fine.
I still get it with SDK
8.0.100-preview.2.23108.9and runtime8.0.0-preview.2.23102.7jkotas commentedon Feb 9, 2023
How do you guarantee that the test execution of the app performed all operations that the app needs to perform dynamically?
One of principles is to avoid designs that require trial and error: https://github.com/dotnet/designs/blob/main/accepted/2020/form-factors.md#technical-roadmap .
AndriySvyryd commentedon Feb 9, 2023
Of course, we can't guarantee that. We discover the user's DbContext and the statically known LINQ queries. But we also plan to provide a hook that would allow the users to explicitly call the dynamic queries and we'll generate code for the exercised combinations. Truly dynamic models and queries won't be supported. We are investigating whether we can provide an analyzer that would find the unsupported queries to avoid trial and error. Also, if the user runs their tests with
<PublishAot>true</PublishAot>we'll throw for anything unsupported.agocke commentedon Mar 1, 2023
Given that this is by design, I'm going to close this issue. If there are more specific concerns, we can address them in a separate issue.
5 remaining items
eerhardt commentedon Mar 3, 2023
@MichalStrehovsky - in trying to fix this issue (main...eerhardt:runtime:Fix81803), I hit a snag:
runtime/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/DelegateHelpers.cs
Lines 24 to 29 in f59a3f5
When running on CoreCLR, this type/method doesn't exist. Is there a way to simulate what
CreateObjectArrayDelegatedoes when running on CoreCLR?MichalStrehovsky commentedon Mar 6, 2023
We would need Ref.Emit on CoreCLR to emulate it, so it's better to not take this codepath and leave the existing Ref.Emit one since it's ref.emit either way. In Native AOT, this relies on the fact that the AOT compiler will generate extra thunks for each delegate type in the app to support this.
I understand it's a bit of a pickle because we don't want ref.emit to work. We might need some sort of backdoor ref-emit.
What I mean is that we would add a private API from CoreLib that we reflection-discover like the above
CreateObjectArrayDelegate. It would set a threadstatic somewhere in CoreLib that would say "this thread now allows Ref.Emit" and e.g. return anIDisposable(that would set it back to ref emit not supported). Then whenever we're about to throw in CoreLib because someone attempted ref-emit, we would additionally check for this threadstatic.inforithmics commentedon Mar 9, 2023
I'm not a Runtime Expert, but in Xamarin the same problem exsists.
Because on iOS only Native Code is allowed (AOT). So to support Dynamic Code the (Mono) Interpreter is used as a FallBack to handle Reflection.Emit and other dynamic Code Patterns.
Project Property for that
<UseInterpreter>true</UseInterpreter>dotnet/android#6556
Respect IsDynamicCodeSupported in more places in Linq.Expressions
Respect IsDynamicCodeSupported in more places in Linq.Expressions (#8…