Hi,

A while back I announced that I was working on a .NET to PIR translator for my final year project at uni. In case you've ever pondered how well it's doing, and you don't read Planet Parrot or my blog, the answer is "pretty well". So far I'm successfully translating:

* Parameters
* Local variables
* Arithemtic and logical ops
* Int/float type conversion
* Checked arithmetic and conversion ops
* Conditional ops and branches
* Non-static method calling, virtual method calling and field access for classes in the same assembly
* Instructions relating to arrays
* Object instantiation, kinda, but missing the all important constructor call

Which brings me to about 140 of the 215 instructions there are to translate. Anyway, onto the real point of the email.

.NET has these managed reference thingies. They're basically like pointers, but safe. What makes them safe is that only certain instructions can create them and the pointer value can't be set directly (we can do that fine - just have a PMC with an underlying struct that hold the pointer, but provide no PMC methods that set that pointer).

Making them work on Parrot is no problem. Making them work without comprimising the safety of the VM is harder. Amongst the things you can get a pointer to are parameters and local variables. Under .NET that means stack locations; with Parrot that means registers. So, imagine this.

1) Get reference to local in the current method
2) Stash that reference somewhere so it lasts longer than the current method's context does, or just return it 3) Assigns to that reference later => BANG! Segfault, or perhaps controlled scribbling to evade security policies etc

Under .NET we have info to track statically where managed references go so we can do escape analysis before ever running the code to check it is safe to run. A .NET VM can implement this just fine. However, on Parrot we can't do this - statically we only know that a P register could hold any old PMC.

Some discussion on IRC later, leo had come up with two suggestions for handling this.

1) A two part solution.

a) Make set an MMD operation. This way, a .NET managed reference PMC knows when it may be about to escape and can say "hey, this ain't allowed" in an exceptionesque kinda way.

b) Add a v-table flag saying "returning me is forbidden" and checking that on any PMCs that get returned. (However, there are subtle issues. For example, we want to be able to pass the PMC to methods that are called from this one - after all, it's how byref passing is implemented. But with tail calls we should probably not do it. Also haven't yet pondered if closures or co-routines may lead to some kinda leakage.)

2) Add a new Reference register type. We have INSP, so we'd also have R too (perhaps). R registers would only have a very limited set of possible operations that could be performed on them; not being able to return them would be one of these. They shouldn't cause an opcode explosion as you won't be able to do that much with them, so few ops that exist now would be useful to act upon them. Obviously, you wouldn't be able to assign just any address to them either. They should be useful beyond running .NET code too. Of course, adding these would require some effort.

Maybe someone has an idea for a better way. Anyhow, that's the problem and the ideas so far. Comments and suggestions very welcome.

Thanks,

Jonathan

Reply via email to