Подтвердить что ты не робот

Почему LambdaExpression.Compile() работает на iOS (Xamarin)?

Так как Xamarin.iOS не поддерживает генерацию кода во время выполнения, почему компиляция() и DynamicInvoke() работают должным образом?

Например, следующий код работает нормально:

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

Является ли Xamarin вычислением дерева выражений во время выполнения вместо испускания кода IL?

4b9b3361

Ответ 1

На платформах, поддерживающих генерацию кода, используется LambdaCompiler на основе Reflection.Emit.

Если это не доступно, выражение интерпретируется с помощью интерпретатора. Например, существуют классы, которые интерпретируют Constant и Add.

Ответ 2

Подробности ограничений Xamarin приведены здесь.

Кажется, что вы не используете что-либо в пространстве имен Reflection.Emit, которое является большим no-no. Ваш код должен быть AOT'd. В противном случае я бы предположил, что это не сработает.

Но там были примеры [родных] разработчиков, пресекающих инструмент статического анализа iOS и обход ограничений динамического кода. Я попытался найти статью, но не смог ее найти.

В любом случае, я не думаю, что ваш сценарий иллюстрирует это. Ваш пример кода по-прежнему будет скомпилирован AOT.

Но вы поднимаете действительно хороший вопрос: в какое время оценивается выражение?

EDIT:

Другой ответ SO по той же теме: Что делает Expression.Compile в Monotouch?

Здесь также есть хорошая информация о Expression.Compile() и "full AOT" здесь: http://www.mono-project.com/docs/advanced/aot/

EDIT: Прочитав еще несколько, я думаю, что знаю, что происходит здесь. Это не значит, что Expression.Compile() не будет работать... это то, что когда ваш пакет приложений iOS подвергается инструменту статического анализа iOS, когда вы отправляете его в хранилище приложений, он не пройдет анализ, потому что он динамически генерирующий код. Итак, вы можете использовать Expression.Compile(), но не ожидайте, что он будет принят в хранилище приложений. Но, как упоминалось в @svick, если вы используете параметр компиляции "полный AOT", ваш Expression.Compile(), вероятно, завершится неудачно во время выполнения или, возможно, даже скомпилирует компиляцию.