(e-mail address removed) (Martin v. =?iso-8859-15?q?L=F6wis?=) wrote in
As for generating MSIL byte codes: This is also possible, and has been
demonstrated. It also has been demonstrated that an initial
implementation is likely to be *very* slow.
The question is whether a Python implementation for .NET would be CLS
compliant (CLS == Common Language Specification). The existing
implementation has shown that this is not possible without giving up
parts of the Python semantics.
The main problem is that functions are first class objects in Python, but
not in the CLS. The CLS uses delegates to refer to functions, and a
delegate encapsulates both an object and a pointer to a method.
The CLS does have pointers to methods, but the situations in which they can
be used are limited by the code validator: there are two MSIL code
sequences which may be used to construct delegates, one for static
methods, one for non-static, both involve pushing a function pointer onto
the stack and then calling the delegate constructor, but in neither case
can the function pointer come from a variable.
To model Python within the environment, you can use a delegate to refer to
a static function (the object reference is null in this case), or to refer
to a bound method, but you cannot easily create a delegate to refer to an
unbound method. This makes any Python code using classes extremely hard to
model.
The original attempt at porting Python to this environment used the
reflection classes to get around this. Using reflection you can get objects
which indirectly reference classes and their methods, you can then create a
delegate from a System.Reflection.MethodInfo object at the point where the
unbound method becomes a bound method. Unfortunately, creating a delegate
from a MethodInfo is a couple of hundred times slower than creating a
delegate from a pointer to a method.
It is even possible to get a pointer to a method and then create a delegate
from it entirely within the constraints applied by the code validator, but
again this uses the Reflection classes and is at least as slow as using the
MethodInfo object.
I have been playing around with a variant on the managed Python compiler,
and I think I have figured a way to implement Python which might just get
around this bottleneck. Unfortunately it requires a lot of refactoring from
the original model, and I'm only working on it occasionally in my spare
time. Basically the idea is to compile static wrapper functions for every
method (at runtime). Obviously this is slow, but at least you only take the
hit once per class. Every unbound method, or bound method can keep a
delegate to the static wrapper, and we lose the overhead of the reflection
classes. Wrapper functions can also wrap constructors.
So far most of my refactoring has been concentrating on replacing the
original runtime with one based on a class hierarchy and modelling some of
the more recent Python behaviour. This simplifies and also speeds up the
code somewhat, although I think I have just about reached the limits I can
achieve before I do the function wrappers.