Fix: WithUseInterpretation() still triggers DynamicMethod on Xamarin.iOS AOT (SIGABRT)#699
Conversation
…t DynamicMethod on AOT platforms Agent-Logs-Url: https://github.com/dadhi/DryIoc/sessions/1e3db970-79d2-494d-8678-db8a1db556d4 Co-authored-by: dadhi <39516+dadhi@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dadhi/DryIoc/sessions/1e3db970-79d2-494d-8678-db8a1db556d4 Co-authored-by: dadhi <39516+dadhi@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dadhi/DryIoc/sessions/1e3db970-79d2-494d-8678-db8a1db556d4 Co-authored-by: dadhi <39516+dadhi@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dadhi/DryIoc/sessions/1e3db970-79d2-494d-8678-db8a1db556d4 Co-authored-by: dadhi <39516+dadhi@users.noreply.github.com>
| // Instead, return a delegate that wraps the DryIoc interpreter so that no code is compiled or emitted at runtime. | ||
| // If the expression cannot be interpreted (e.g., it uses Made.Of with complex arbitrary expressions | ||
| // not covered by the DryIoc Interpreter), a ContainerException with a helpful message is thrown. | ||
| var capturedExpr = expression; |
There was a problem hiding this comment.
Why capturedExpr, why not use expression directly?
There was a problem hiding this comment.
Removed in 2aeaf03 - expression is already a local variable (reassigned from NormalizeExpression()) so capturing it directly works fine.
| ServiceTypeIsNull = Of("Registered service type is null"), | ||
| RegisterAttributedUnsupportedReuseType = Of("Not support reuse type {0} in the RegisterAttribute."); | ||
| RegisterAttributedUnsupportedReuseType = Of("Not support reuse type {0} in the RegisterAttribute."), | ||
| UnableToInterpretExpression = Of( |
There was a problem hiding this comment.
Add the test which actually goes to this condition branch and throws this expression, with the complex Made.Of or someth not supported by DryIoc interpreter.
There was a problem hiding this comment.
Added Test_UnableToInterpretExpression_thrown_for_unsupported_expression_with_UseInterpretation in 2aeaf03. It uses ExpressionFactory with a Conditional (ternary) expression — ExprType.Conditional is not in the interpreter's TryInterpret switch, so it hits default: return false. With UseInterpretation=true, the fix throws ContainerException(Error.UnableToInterpretExpression) instead of falling back to Expression.Compile().
…pression with unsupported expression Agent-Logs-Url: https://github.com/dadhi/DryIoc/sessions/ee4d901f-a04e-4144-a30a-ab1c31e16e78 Co-authored-by: dadhi <39516+dadhi@users.noreply.github.com>
When
Rules.WithUseInterpretation()is configured (intended for AOT platforms like Xamarin.iOS), DryIoc could still internally callExpression.Compile(preferInterpretation: true)as a fallback when the DryIoc interpreter failed for an expression. On Mono/AOT, this internally creates aDynamicMethod, causingPlatformNotSupportedException/ SIGABRT — typically observed on second navigation in Xamarin.Forms apps.Changes
FactoryDelegateCompiler.CompileOrInterpretFactoryDelegate: WhenpreferInterpretation = true, instead of falling back toExpression.Compile(), return a delegate that wraps the DryIoc interpreter directly. This eliminates allDynamicMethod/ IL emit paths whenUseInterpretation = true.Error.UnableToInterpretExpression: New error code with an actionable message thrown when the interpreter cannot handle an expression (e.g.,ExpressionFactorywith complex arbitrary expressions likeConditionalthat are not covered by the DryIoc interpreter). Previously this silently fell back to compilation, which is the wrong behavior on AOT platforms.GHIssue571tests: Added tests covering:Test_UnableToInterpretExpression_thrown_for_unsupported_expression_with_UseInterpretation: verifies that when anExpressionFactoryproduces aConditionalexpression (not handled by the DryIoc interpreter), aContainerException(Error.UnableToInterpretExpression)is thrown instead of falling back toExpression.Compile()/DynamicMethod.Behavioral note: On JIT platforms (Android, .NET Core),
CompileOrInterpretFactoryDelegate(false)is unchanged — FEC +Expression.Compile()are still used whenUseInterpretation = false. The only affected code path is thepreferInterpretation = truebranch.