13

Since Xamarin.iOS doesn't support code generation at runtime, why do Compile() and DynamicInvoke() work as expected?

For example, the following code works fine:

var lambda = Expression.Lambda(
                          Expression.Add(
                              Expression.Constant(1),
                              Expression.Constant(2)
                          )
             );

var f = lambda.Compile();
var result = f.DynamicInvoke();

// result==3 at this point

Is Xamarin evaluating the expression tree at runtime instead of emitting IL code?

Philippe Leybaert
  • 168,566
  • 31
  • 210
  • 223

2 Answers2

13

On platforms that support code generation, Reflection.Emit-based LambdaCompiler is used.

If that's not available, the expression is interpreted using the interpreter. For example, there are classes that interpret Constant and Add.

svick
  • 236,525
  • 50
  • 385
  • 514
  • I was suspecting something like that. Is this documented anywhere? – Philippe Leybaert Mar 27 '15 at 03:33
  • While your answer makes sense, I'd like to know if there's a reference or documentation that confirms this. – Philippe Leybaert Mar 31 '15 at 20:30
  • @PhilippeLeybaert I couldn't find any, which is why I looked at the source. – svick Mar 31 '15 at 20:56
  • In Mono/Xamarin, the expression will not be interpreted. It will be ahead-of-time compiled (AOT). http://www.mono-project.com/docs/advanced/aot/ – NovaJoe Apr 03 '15 at 15:26
  • 2
    @NovaJoe, I believe you are mistaken. The document to which you refer explicitly says that `Expression.Compile` is *not* supported by the AOT under "Known Limitations". – Kirk Woll Jul 15 '15 at 14:50
2

The details of the Xamarin limitations are here.

You don't seem to be using anything in the Reflection.Emit namespace, which is the big no-no. Your code must still be AOT'd. Otherwise, I would imagine it would not work.

But there HAVE been examples of [native] developers thwarting the iOS static analysis tool and circumventing the dynamic code restriction. I tried to locate the article, but couldn't find it.

Anyway, I don't think your scenario exemplifies that. Your code example will still be AOT-compiled.

But you raise a really good question: at what time does the expression get evaluated?

EDIT:

Another SO answer on the same topic: What does Expression.Compile do on Monotouch?

There's also some good info on Expression.Compile() and "full AOT" here: http://www.mono-project.com/docs/advanced/aot/

EDIT: After reading some more, I think I know what's going on here. It's not that Expression.Compile() won't work...it's that when your iOS app bundle is subjected to the iOS static analysis tool when you submit it to the app store, it will not pass the analysis, because it is dynamically generating code. So, sure, you can use Expression.Compile(), but don't expect it to be accepted into the app store. But as mentioned by @svick, if you use the "full AOT" compile option, your Expression.Compile() will probably fail at runtime, or perhaps even fail compilation.

Community
  • 1
  • 1
NovaJoe
  • 4,595
  • 6
  • 29
  • 43
  • 2
    Are you saying that the `Expression` will be AOT? How could that possibly work, considering that the `Expression` is built at runtime? – svick Mar 27 '15 at 02:26
  • @svick: another SO answer on the same topic seems to suggest, as I have, that expressions get pre-compiled by the AOT compiler when in a Xamarin.iOS app: http://stackoverflow.com/questions/24977939/what-does-expression-compile-do-on-monotouch – NovaJoe Apr 03 '15 at 14:59
  • @svick: To re-iterate, what I'm saying is that my understanding is that Expression is NOT built at runtime when you're using Mono's AOT compiler. It's built at compile time. – NovaJoe Apr 03 '15 at 15:18
  • 1
    My point is that that's not possible, since the expression can depend on something that's only known at runtime. – svick Apr 04 '15 at 12:51
  • The other answer pretty much just says "It works" and then makes some unsubstantiated claims. And if I read the docs correctly, it seems to say that `Expression.Compile()` should not work with full AOT. – svick Apr 04 '15 at 12:57
  • Hmmm...I concede that the AOT docs DO indeed suggest that compiling with full AOT will prevent Expression.Compile() from working properly, as you've said. My mistake. – NovaJoe Apr 04 '15 at 16:55