dynamicexpresso / DynamicExpresso

C# expressions interpreter
http://dynamic-expresso.azurewebsites.net/
MIT License
1.91k stars 364 forks source link

Missing Binary Operator in Unity IL2CPP #275

Closed jjolley closed 1 year ago

jjolley commented 1 year ago

I receive the following an error when evaluating an expression only in a build. I'm using Unity and compiling to an IL2CPP platform

The expression is:

Source.Level < 4 ? (.6f Mathf.Pow(1.63f, Source.ZeroBasedLevel)) : (Mathf.Pow(1.15f, Source.ZeroBasedLevel) + 0.5 Source.Level)

The error is:

InvalidOperationException: The binary operator Multiply is not defined for the types 'System.Double' and 'System.Int32'. at System.Linq.Expressions.Expression.GetUserDefinedBinaryOperatorOrThrow (System.Linq.Expressions.ExpressionType binaryType, System.String name, System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right, System.Boolean liftToNull) [0x00000] in <00000000000000000000000000000000>:0 at System.Linq.Expressions.Expression.Multiply (System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right, System.Reflection.MethodInfo method) [0x00000] in <00000000000000000000000000000000>:0 at System.Linq.Expressions.Expression.Multiply (System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right) [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseMultiplicative () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseAdditive () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseTypeTesting () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseComparison () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseLogicalAnd () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseLogicalXor () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseLogicalOr () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseConditionalAnd () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseConditionalOr () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseConditional () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseAssignment () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseExpressionSegment () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseParenExpression () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParsePrimaryStart () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParsePrimary () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseUnary () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseMultiplicative () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseAdditive () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseTypeTesting () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseComparison () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseLogicalAnd () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseLogicalXor () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseLogicalOr () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseConditionalAnd () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseConditionalOr () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseConditional () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseAssignment () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseExpressionSegment () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseConditional () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseAssignment () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseExpressionSegment () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.ParseExpressionSegment (System.Type returnType) [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.Parse () [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Parsing.Parser.Parse (DynamicExpresso.ParserArguments arguments) [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Interpreter.ParseAsLambda (System.String expressionText, System.Type expressionType, DynamicExpresso.Parameter[] parameters) [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Interpreter.ParseAs[TDelegate] (System.String expressionText, System.String[] parametersNames) [0x00000] in <00000000000000000000000000000000>:0 at DynamicExpresso.Interpreter.ParseAsDelegate[TDelegate] (System.String expressionText, System.String[] parametersNames) [0x00000] in <00000000000000000000000000000000>:0

metoule commented 1 year ago

HI @jjolley, thanks for reporting the issue! Unfortunately, neither I not @davideicardi use Unity, so it's difficult for us to debug what the issue can be. Another issue was reported in Unity, and one of the potential solution was:

Not sure if people are still interested in this topic. I just ran into the same problem. And I found the reason why it happened but could not find any solution. Tried linker.xml as recommended by documentation, it did not work (might be me doing it wrong).

Here is why: When building with IL2CPP in Unity, some code will be automatically stripped if the engine does not find any usage of the code in your project. If you change to Mono which does not strip any code, it should probably work as fine.

Can you try that?

jjolley commented 1 year ago

Thanks for the response and the great library!

Unfortunately switching to Mono isn't an option. The platform I'm targeting only has IL2CPP. I'm trying to use link.xml to include the right assembly that's being stripped, but I'm not sure what that would be. Do you know in the code where you would set user defined binary operators for multiply?

davideicardi commented 1 year ago

@jjolley Maybe you can configure some options: https://docs.unity3d.com/Manual/ManagedCodeStripping.html