Sam Ruby <[EMAIL PROTECTED]> wrote:
> Leopold Toetsch wrote:

>> ... But that doesn't
>> work fur user methods, especially if there is no indication that a user
>> function is used as a method in the first place.
>>
>>   def find(s, sub):
>>     ...

> In Python, this is statically determinable.  If that sequence is
> directly nested inside a class, it is a method, otherwise it is a
> function.

No, we had that several times. You did show examples, where this isn't
true. Here is another one:

def add(l, r):
    print "in add"
    return 42

class C(object):
    __add__ = add

c = C()
print c + 1

"add" is just a plain function. There is no indication whatsoever that
it might be used as a method, when "add" is compiled. But as infix<+> is
a method call "l.__add__(r)" this doesn't work, if the object is in P2.

>> I've proposed several times that arguments including the object should be
>> passed from P5 up. The invocant - if any - can still be reachable with
>> the C<interpinfo> opcode, but it'll be probably used just in calls to SUPER
>> or next_method or such.

> Less shifting will be required if the object is passed in P2.

That's only true for NCI methods. And IIRC, your arguments were the same
some time ago. How do you compile the "add" above, when the object is in
P2?

>>>Notes: at the moment, every Python method call creates a bound object,
>>>and shifts PMC arguments.
>>
>> This shouldn't be necessary for "normal" method calls like:
>>
>>   s.f("r")

> But this translates into two VTABLE calls.  find_method and invoke.
> find_method needs to return a bound method.

Why don't you just use the "callmethodcc" opcode? That's exactly what is
happening here.

> A find_method_and_invoke VTABLE entry (or more simply call_method) would
> not need to return the intermediary bound method.

There is no need for an intermediate object, if it's a plain method
call.

>>>If there were a call_method VTABLE entry and if P2 were passed into
>>>methods, all of this would be unecessary in the majority of cases.
>>
>> A separate vtable slot doesn't really help. Code that looks like a
>> function call can actually be a method call (and vv). Separating the
>> call into two vtables will just duplicate the call sequence. But let's
>> first convince Dan that all arguments are passed from P5 up, then we'll
>> see what we have.

> Less shifting will be required if the object is passed in P2.

See above.

And why are you duplicating object arguments into P5, if the object
should go into P2?

,--[ dynclasses/pyint.pmc ]-----------
|     METHOD PMC* __hex__(PMC *self) {
`-------------------------------------

You are inventing an additional "self" argument here just to work around
the problem that the object is passed in P2. The actual object "pmc" is
ignored:

,--[ dynclasses/pyint.c ]---------------------------------------
| PMC*
| Parrot_PyInt___hex__(Interp* interpreter, PMC* pmc, PMC *self)
`---------------------------------------------------------------

As said in another message, there is no problem with NCI methods. It's
just a matter of translating the "O" signature char.

The problem are user functions. There might be an indication that's a
method (like a definition inside a class block) - but not always. And if
the latter is the case *only once*, we just have to call all methods
with plain function call argument passing. Or prepend *all* functions
with an argument check wrapper that shift arguments around, if the call
was actually a method call.

> - Sam Ruby

leo

Reply via email to