2

我想在 Silverlight 应用程序中运行一些任意用户代码。当然,我想嵌入一个图灵完备的语言(足够简单),但不想让用户在编写一些糟糕的(非终止)代码时锁定他们的浏览器。我不是要解决Halting Problem,只需在后台线程上运行此用户代码并按一下按钮即可终止它。

即使我愿意,我也不能在 Silverlight 中使用 Thread.Abort,那么如何中断后台解释器线程呢?

我目前的想法:

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

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

4

1 回答 1

0

修改 IronPython 或 IronRuby 来做到这一点不会太困难。最终,您只需要编写一个 ExpressionVisitor,它会在后面的分支(循环,可能是 goto)和方法调用中插入轮询。这应该很容易,例如处理循环可能如下所示:

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 上运行此表达式访问者。

于 2011-11-03T04:32:41.547 回答