Интерпретируемый интерпретированный код пользователя в Silverlight - PullRequest
2 голосов
/ 30 октября 2011

Я хотел бы запустить произвольный пользовательский код в приложении Silverlight.Конечно, я хочу встроить язык, полный Тьюринга (достаточно просто), но не хочу, чтобы пользователь мог заблокировать свой браузер, если он пишет какой-то плохой (не заканчивающийся) код.Я не прошу решить проблему остановки , просто запустите этот код пользователя в фоновом потоке и завершите его нажатием кнопки.

Я не могу использовать Thread.Abortв Silverlight, даже если я хочу, так как я могу прервать поток интерпретатора фона?

Мои текущие идеи:

  • Если я интерпретирую какой-либо язык вручную, конечно, я могу остановить выполнение, когда я хочу
  • Я мог бы использовать Reflection.Emit или компилироватьдерево выражений и вставьте аналогичные проверки для досрочного завершения
  • Измените существующий компилятор, чтобы сгенерировать код, который делает это (F # или IronPython, может быть?)
  • Постобработка IL, сгенерированная существующим инструментомэто правило исключает языки на основе DLR?)

Не могу не подумать, что должно быть более простое решение.

1 Ответ

0 голосов
/ 03 ноября 2011

Модификация IronPython или IronRuby для этого не будет слишком сложной.В конечном итоге вам просто нужно написать ExpressionVisitor, который вставляет опрос в ответвления (циклы, может быть gotos) и вызовы методов.Это должно быть довольно просто, например, обработка циклов может выглядеть следующим образом:

public class AbortPollRewriter : ExpressionVisitor {
    protected override Expression VisitLoop(LoopExpression node) {
        var body = Expression.Block(
            Expression.Call(typeof(AbortPollRewriter).GetMethod("Poll")),
            node.Body
        );
        return Expression.Loop(body, node.BreakLabel, node.ContinueLabel);
    }

    [ThreadStatic]
    private static bool _aborting;

    public static void Abort() {
        _aborting = true;
    }

    public static void Poll() {
        if (_aborting) {
            throw new MyThreadAbortException();
        }
    }
}

class MyThreadAbortException : Exception {
}

Для IronPython вы можете запустить этот посетитель выражения для лямбда-выражения, предоставленного при создании объектов FunctionCode.

...