I'd like to run some arbitrary user code in a Silverlight application. Of course I want to embed a Turing-complete language (easy enough), but don't want to allow the user to lock up their browser if they write some bad (non-terminating) code. I'm not asking to solve the Halting Problem, just run this user code on a background thread and terminate it at the press of a button.
I can't use Thread.Abort in Silverlight even if I want to, so how can I interrupt the background interpreter thread?
My current ideas:
I can't help think there has to be a simpler solution.
Modifying IronPython or IronRuby to do this wouldn't be too difficult. Ultimately you'll just need to write a ExpressionVisitor which inserts polling at back branches (loops, maybe gotos) and method calls. This should be pretty easy, for example handling loops could look like:
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 {
}
For IronPython you could then run this expression visitor on the lambda provided when FunctionCode objects are constructed.