On 03/13/04 Mark Sparshatt wrote:
> One difficulty is when calling class methods some languages require that 
> you provide the class object as the receiver (Ruby and c# do this) while 
> some languages let you use an instance of the class as the receiver 
> (Java does this)

I think you're confusing what it looks like and what it does.
When designing a VM such as parrot it's very important to keep the two
things separate.
"What it looks like" is the realm of the compiler. The compiler maps
from the language syntax to the execution capabilities provided by the
virtual machine and runtime. Even if from the syntax point of view
it looks like static methods in C# require the class name to invoke
them, this doesn't mean a 'class object' is involved at all. Same with
java: if it's allowed to call a static method with the syntax:
        instance_of_class.static_method_of_class ();
it doesn't mean instance_of_class is involved in the call: it isn't.
The compiler will find static_method_of_class and emit a direct call to it,
possibly discarding instance_of_class completely (unless it's an
expression with possible side effects, but in any case, the instance
object is not involved in the call).

"What it does" is the realm of the virtual machine or runtime.
The virtual machine needs to provide enough power for the compiler
to be able to implement its specific languuage semantics (either
directly or through helper methods/libraries). Of course, if the VM
provides more than one way to do it, the compiler should try to use the
more efficient one. For example, on the CLR you can call a static method
in at least three ways:
        * directly from IL code (same overhead as a direct C function call)
        * using reflection (provides lots of flexibility, since it can
        be done at runtime, arguments are converted to the correct
        types if needed etc. Of course the price to pay is slowness...)
        * delegate invocation: some of the benefits of a reflection call
        with an overhead just slightly bigger than a direct call

I think parrot should provide two mechanisms: a fast one for languages
that can take advantage of it and a more dynamic one for use by the
other implementations. Of course the main issue becomes: what happens
when two different langauges with different semantics need to call each
others's methods? This is the main issue that parrot faces if it is to
become a real VM for dynamic languages, but sadly this problem space has
not been addressed yet, mostly because of the lack of real langauge
implementations (but the pie contest is rapidly approaching and it's
likely to be a big driving force:-) The PHP compiler is also progressing
nicely from what I hear, so it's likely that by summer some people
will have to actually deal with inter-languages calls).

Some of the call issues are present already: I don't remember if it has
been addressed somewhere already, but how does parrot deal with
perl (arguments passed in the @_ array) with the parrot call convention
that passes some args in registers and some not?
For example, consider:
        sub my_func {
                my ($arg1) = shift;
                do_something (@_);
        }
When it is called with:
        my_func (1);
        my_func (1, 2, 3, 4, ..., 11, 12, 13);
        my_func (@an_array);
Since the call has no prototype some args go in registers and some in
the overflow array. In the first case my_func will need to build the @_
array from the first PMC arg register. In the second case the compiler
needs to create a temporary array and put some args in registers and
some in the overflow temp array. When called, my_func needs to gather
all the args and put them in the @_ array. 
In the third case the compiler needs to discard the passed array, put
some of the elements in registers and some in a newly created temp array
(the overflow array) unless it can play tricks by modifying @an_array
(but this is only safe when @an_array is a temporary list, such as one
returned from sort etc.). Again, at the method prolog, my_func needs to
reconstruct the argument array @_ from args in registers and in the
overflow array. Some of the shuffling could be avoided if @_ becomes
a magic array which keeps some data in registers and some in the
overflow array, but this has many issues itself, since the first
arguments are in registers which could be overwritten at the first call.
So it looks like there is already a lot of complexity and memory
shuffling: has anyone generated the code (maybe by hand) to implement in
parrot something like the above scenario and measured the speed
characteristics vs the equivalent perl5/python code (I don't know,
though, if in python the call semantics are similar to the perl5 ones...)?
Thanks.

lupus

-- 
-----------------------------------------------------------------
[EMAIL PROTECTED]                                     debian/rules
[EMAIL PROTECTED]                             Monkeys do it better

Reply via email to