Skip to content

Make ParameterDefaultValue.TryGetDefaultValue bitcode compliant #50439

Closed
@maryamariyan

Description

@maryamariyan

Description taken from the closed PR: #47197

Context

When using this code in Xamarin apps targeting iOS or watchOS, the code failed when bitcode was enabled since a catch exception with a when block is not allowed/bitcode compliant.
In order to get this code working on bitcode enabled apps (all apps running in watchOS must have bitcode enabled), the closed PR #47197 removes the when and instead moves the condition into the catch block.

The same scenario also happened in other parts of the codebase. See mono/mono#19451 for example.

Example Stacktrace

This method contains IL not supported when compiled to bitcode.
 at Microsoft.Extensions.Internal.ParameterDefaultValue.TryGetDefaultValue (System.Reflection.ParameterInfo parameter, System.Object& defaultValue) <0x23bfb1c + 0x00078> in <84525b045edb404392d95a20a1ee4f64>:0 
  at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites (System.Type serviceType, System.Type implementationType, Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteChain callSiteChain, System.Reflection.ParameterInfo[] parameters, System.Boolean throwIfCallSiteNotFound) <0x23ce248 + 0x001d0> in <84525b045edb404392d95a20a1ee4f64>:0 
  at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite (Microsoft.Extensions.DependencyInjection.ServiceLookup.ResultCache lifetime, System.Type serviceType, System.Type implementationType, Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteChain callSiteChain) <0x23ccb20 + 0x00500> in <84525b045edb404392d95a20a1ee4f64>:0 
  at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite (System.Type serviceType, Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteChain callSiteChain) <0x23ca600 + 0x001ac> in <84525b045edb404392d95a20a1ee4f64>:0 
  at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory+<>c__DisplayClass7_0.<GetCallSite>b__0 (System.Type type) <0x23cf1c4 + 0x000ac> in <84525b045edb404392d95a20a1ee4f64>:0 
  at (wrapper delegate-invoke) System.Func`2[System.Type,Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite].invoke_TResult_T(System.Type)
  at System.Collections.Concurrent.ConcurrentDictionary`2[TKey,TValue].GetOrAdd (TKey_REF key, System.Func`2[T,TResult] valueFactory) <0x12b5f84 + 0x0036c> in <94cd4c1255b24edb9c7f402e2ad54ddc>:0 
  at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.GetCallSite (System.Type serviceType, Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteChain callSite<…>
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x106fbb0 + 0x00084> in <94cd4c1255b24edb9c7f402e2ad54ddc>:0 
  at System.Threading.Tasks.Task.ExecuteWithThreadLocal (System.Threading.Tasks.Task& currentTaskSlot) <0x109e3d8 + 0x00144> in <94cd4c1255b24edb9c7f402e2ad54ddc>:0 
  at System.Threading.Tasks.Task.ExecuteEntry (System.Boolean bPreventDoubleExecution) <0x1097494 + 0x00224> in <94cd4c1255b24edb9c7f402e2ad54ddc>:0 
  at System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () <0x1097418 + 0x00070> in <94cd4c1255b24edb9c7f402e2ad54ddc>:0 
  at System.Threading.ThreadPoolWorkQueue.Dispatch () <0x1078904 + 0x003c8> in <94cd4c1255b24edb9c7f402e2ad54ddc>:0 
  at (wrapper delegate-invoke) System.Func`1[System.Boolean].invoke_TResult()
  at ObjCRuntime.Runtime.ThreadPoolDispatcher (System.Func`1[TResult] callback) <0x16ef750<…>
  at System.Threading.Tasks.UnwrapPromise`1[TResult].ProcessCompletedOuterTask (System.Threading.Tasks.Task task) <0x151afc8 + 0x0019c> in <94cd4c1255b24edb9c7f402e2ad54ddc>:0 
  at System.Threading.Tasks.UnwrapPromise`1[TResult].InvokeCore (System.Threading.Tasks.Task completingTask) <0x151acd8 + 0x00098> in <94cd4c1255b24edb9c7f402e2ad54ddc>:0 
  at System.Threading.Tasks.UnwrapPromise`1[TResult].Invoke (System.Threading.Tasks.Task completingTask) <0x151ab3c + 0x000e0> in <94cd4c1255b24edb9c7f402e2ad54ddc>:0 
  at System.Threading.Tasks.Task.FinishContinuations () <0x10998f0 + 0x01260> in <94cd4c1255b24edb9c7f402e2ad54ddc>:0 
  at System.Threading.Tasks.Task.FinishStageThree () <0x10963fc + 0x00088> in <94cd4c1255b24edb9c7f402e2ad54ddc>:0 
  at System.Threading.Tasks.Task.FinishStageTwo () <0x10960cc + 0x001e8> in <94cd4c1255b24edb9c7f402e2ad54ddc>:0 
  at System.Threading.Tasks.Task.Finish (System.Boolean bUserDelegateExecuted) <0x1095d94 + 0x000e4> in <94cd4c1255b24edb9c7f402e2ad54ddc>:0 
<…>

Planned fix:

What we want is to add $(NetCoreAppCurrent) TFM for these assemblies:

<TargetFrameworks>netstandard2.1;netstandard2.0;net461</TargetFrameworks>

The try-catch workaround (from PR #47197) block will remain for older frameworks (i.e. netstandard).
And the whole try/catch workaround can be removed for netcore build (due to fix dotnet/coreclr#17877).

Reference to source code:

catch (FormatException) when (parameter.ParameterType == typeof(DateTime))

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions