Benjamin Wootton has been working on Mono's Code Access Security (CAS) support. CAS is a way of creating arbitrary "sandboxes" in the .NET environment. The idea here is to load and execute untrusted side-by-side with your trusted code code without compromising your application. Similar in spirit to Java's security model.
CAS is needed for the various "click-once" setups for downloading, running and updating applications over the web, but more advanced uses enable scenarios like running untrusted plugins in a trusted application (for instance, a file format importer downloaded from the network, or plugins for your application which you do not necessarily want to trust).
You can read his list of requirements here; The project status page (with all his patches to add CAS to Mono) and a screenshot of his Mono CAS Configuration tool.
I have been working on anonymous method support for the compiler in stages. My latest patch for the curious lives here.
The first one was to implement the implicit method group conversions to delegates, that one allows you to write things like:
void Method () { button.Clicked += clicked_handler; ... } void clicked_handler () { }
The second stage was to handle anonymous method declarations inline, and move the body of the code into an helper method in a chunk like this:
void Method () { button.Clicked += delegate { Console.WriteLine ("hello"); } }
Until that point things were relatively simple, the next step was a lot more tricky, and it involved capturing local variables:
void Method () { int i = 0; button.Clicked += delegate { Console.WriteLine (i); } }
The above code needs to be compiled into something like:
void Method () { Locals1 __locals = new Locals1 (); locals1.i = 0; button.Clicked += locals1.__AnonymousMethod1; } class Locals1 { int i; void _AnonymousMethod () { Console.WriteLine (i); } }
Things get more complicated when you add multiple levels of scopes to variables:
void Method () { for (int i = 0; i < 10; i++){ int j = 0; button.Clicked += delegate { Console.WriteLine (i + j); } int z = i + j; } }
The above needs to generate roughly this:
void Method () { Local1 locals1 = new Locals1 (); locals1.i = i; for (int i = 0; i < 10; i++){ Locals2 locals2 = new Locals2 (); locals2.locals1 = locals1; locals2.j = 0; button.Clicked += locals2.AnonymousMethod1; z = locals2.locals1.i + locals2.j; } } class Locals1 { int i; } class Locals2 { Locals1 locals1; int j; void AnonymousMethod () { Console.WriteLine (locals1.i, j); } }
So fairly tricky: the variable can be accessed from the method containing the anonymous method.
One of the trickiest parts is the process that guesses the return value for the anonymous method: it might seem like inference is at work, but in fact during the resolution process we know the type we requiere, so the compiler triggers the resolution of the inner block when it gets this information.
Another complex bit was that the resolution/emit phases of the compiler had to be completely decoupled (they were already partially decoupled) because it is necessary to identify any variables that might be captured before we can even generate the first line of the block.
The patch is my work-in-progress code, it can not be checked into CVS just yet, since it breaks the iterator support in the compiler, so that must be fixed first.
I need to finish my write up and post the pictures of the event, but that will come later ;-)
Posted on 10 Mar 2004