Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does Expression.Compile do on Monotouch?

So Expression.Compile does the following

Compiles the lambda expression described by the expression tree into executable code and produces a delegate that represents the lambda expression.

And it is available in Portable Class Libraries.

However when running .net through Monotouch dynamic code generation is not supported

Since the iPhone's kernel prevents an application from generating code dynamically Mono on the iPhone does not support any form of dynamic code generation.

So based on that Xamarin on IOS cannot support Expression.Compile.

So what happens when you call Expression.Compile Xamarin on IOS ? Does it throw and exception, and if so what exception? And is it documented anywhere?

like image 256
Simon Avatar asked Jul 27 '14 04:07

Simon


2 Answers

The code is compiled with AOT option so it will actually not be compiled at runtime (I don't know the details that happens in the background on Compile()). The example from Microsoft documentation runs just fine on iOS device, no exceptions.

    public override void FinishedLaunching(UIApplication application)
    {
        System.Linq.Expressions.Expression<Func<int, bool>> expr = i => i < 5;
        // Compile the expression tree into executable code.
        Func<int, bool> deleg = expr.Compile();
        // Invoke the method and print the output.
        Console.WriteLine("deleg(4) = {0}", deleg(4));
    }

You cannot create IL code at runtime (System.Reflection.Emit) and there are also restrictions on using Reflection with certain linker options, some more info on this thread. There might be expressions that do not AOT compile and in those cases you would get an exception at runtime about trying to JIT compile with AOT-only option.

like image 165
SKall Avatar answered Sep 20 '22 13:09

SKall


The new Compile(bool) overload may make this clearer if you take a look, though the docs don't (currently) give much info on the details.

Compile() used to always do IL-generation, and was hence not available with AOT.

For some time now (I forget when it came in) Compile() can now also do "compilation" to a set of objects representing operations (they operate quite similarly to IL, with a stack represented by a fixed-length object[]), which uses reflection (but not `Reflection.Emit' reflection) for method calls and its own code for basic operations like arithmetic.

Compile(bool) let's you ask for IL-generation (false) or interpretation (true), but it's treated as a preference rather than a demand; if you ask for IL-generation on a platform that only has interpretation, you get interpretation, and vice versa. Mostly if you can do either you want IL generation (generally faster, and there's a few limitations on the interpreter) but you might want to rule out there being differences between platform, or you might find that while on average the interpreted delegates are slower to execute, on average the Compile() step itself is faster with the interpreter and sometimes if you are creating several one-off expressions the total time is faster with the interpreter. (But not always, if you try this for performance reasons, profile and/or consider caching delegates if you can).

This incidentally means that System.Linq.Expressions contains code representing one language (expressions are a sort of language in themselves), written in a second (C#), which are not only compiled into a third language (CIL) but also into yet another language (since the internal structures for interpretation are yet another language of sorts) which it contains an interpreter for. This is a big part of why I find it a fun project to contribute to :)

like image 20
Jon Hanna Avatar answered Sep 22 '22 13:09

Jon Hanna