Silverlight中的中断解释用户代码

时间:2011-10-30 10:54:47

标签: .net silverlight f# ironpython embedded-language

我想在Silverlight应用程序中运行一些任意用户代码。当然我想嵌入一个图灵完备语言(很容易),但是如果他们写了一些坏的(非终止)代码,就不想让用户锁定他们的浏览器。我不是要求解决Halting Problem,只需在后台线程上运行此用户代码,然后按下按钮即可终止它。

即使我想要,也无法在Silverlight中使用Thread.Abort,那么如何中断后台解释器线程呢?

我目前的想法:

  • 如果我手工解释某种语言,当然我可以在我想要时停止执行
  • 我可以使用Reflection.Emit或编译表达式树,并插入类似的检查以提前终止
  • 修改现有编译器以生成执行此操作的代码(可能是F#或IronPython?)
  • 现有工具生成的后处理IL(这会排除基于DLR的语言吗?)

我不禁认为必须有一个更简单的解决方案。

1 个答案:

答案 0 :(得分:0)

修改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对象时提供的lambda上运行此表达式visitor。