Re: runops_args vs NCI

2004-12-18 Thread Leopold Toetsch
Sam Ruby wrote:
However, VTABLE_invoke on NCI methods is where the real work is done 
(including reading from and writing to registers), and a null dest is 
returned.
One more remark:
This is classes/nci.pmc:invoke
void* invoke (void * next) {
Parrot_csub_t func = (Parrot_csub_t)D2FPTR(PMC_data(SELF));
func(INTERP, SELF);
return next;
}
It's not returning NULL.
leo


Re: runops_args vs NCI

2004-12-18 Thread Sam Ruby
Leopold Toetsch wrote:
Sam Ruby wrote:
However, VTABLE_invoke on NCI methods is where the real work is done 
(including reading from and writing to registers), and a null dest is 
returned.
One more remark:
This is classes/nci.pmc:invoke
void* invoke (void * next) {
Parrot_csub_t func = (Parrot_csub_t)D2FPTR(PMC_data(SELF));
func(INTERP, SELF);
return next;
}
It's not returning NULL.
Fixed.
- Sam Ruby


Re: runops_args vs NCI

2004-12-17 Thread Leopold Toetsch
Sam Ruby wrote:
However, VTABLE_invoke on NCI methods is where the real work is done 
(including reading from and writing to registers), and a null dest is 
returned.
Ouch. Sorry, probably cut'n'paste code, relicts or whatever. runops_* 
isn't supposed to be called for NCI methods. It's for running PASM 
opcodes. A NCI methods wraps a C function to be callable by PASM. If we 
are calling a NCI function from C, we can run the code diretly too.

I'll fix that.
- Sam Ruby
leo


Re: runops_args vs NCI

2004-12-17 Thread Sam Ruby
Leopold Toetsch wrote:
Sam Ruby wrote:
However, VTABLE_invoke on NCI methods is where the real work is done 
(including reading from and writing to registers), and a null dest is 
returned.
Ouch. Sorry, probably cut'n'paste code, relicts or whatever. runops_* 
isn't supposed to be called for NCI methods. It's for running PASM 
opcodes. A NCI methods wraps a C function to be callable by PASM. If we 
are calling a NCI function from C, we can run the code diretly too.

I'll fix that.
I have a number of cases (filter, map, reduce), where I am passed an 
arbirary sub and need to call it.  I should not have to know how the sub 
is implemented.

So, what you are telling me is that I need to clone runops_args and fix 
it right.   I'll do that.

- Sam Ruby


Re: runops_args vs NCI

2004-12-17 Thread Leopold Toetsch
Sam Ruby wrote:
Leopold Toetsch wrote:
Sam Ruby wrote:
However, VTABLE_invoke on NCI methods is where the real work is 
done (including reading from and writing to registers), and a null 
dest is returned.

Ouch. Sorry, probably cut'n'paste code, relicts or whatever. 
runops_* isn't supposed to be called for NCI methods. It's for 
running PASM opcodes. A NCI methods wraps a C function to be callable 
by PASM. If we are calling a NCI function from C, we can run the code 
diretly too.

I'll fix that.

I have a number of cases (filter, map, reduce), where I am passed an 
arbirary sub and need to call it.  I should not have to know how the sub 
is implemented.
Just invoke it.
So, what you are telling me is that I need to clone runops_args and fix 
it right.   I'll do that.
Argh. I didn't tell you that. The interface to run an arbitrary piece of 
code is VTABLE_invoke. The runops_fromc* functions run *opcodes* from 
inside C.

- Sam Ruby
leo


Re: runops_args vs NCI

2004-12-17 Thread Sam Ruby
Leopold Toetsch wrote:
Sam Ruby wrote:
Leopold Toetsch wrote:
Sam Ruby wrote:
However, VTABLE_invoke on NCI methods is where the real work is 
done (including reading from and writing to registers), and a null 
dest is returned.
Ouch. Sorry, probably cut'n'paste code, relicts or whatever. 
runops_* isn't supposed to be called for NCI methods. It's for 
running PASM opcodes. A NCI methods wraps a C function to be callable 
by PASM. If we are calling a NCI function from C, we can run the code 
diretly too.

I'll fix that.
I have a number of cases (filter, map, reduce), where I am passed an 
arbirary sub and need to call it.  I should not have to know how the 
sub is implemented.
Just invoke it.
So, what you are telling me is that I need to clone runops_args and 
fix it right.   I'll do that.
Argh. I didn't tell you that. The interface to run an arbitrary piece of 
code is VTABLE_invoke. The runops_fromc* functions run *opcodes* from 
inside C.
Grrr.  First you tell me:
Crunops is a low-level function that awaits all properly setup.
Around that are more function that e.g. create a return continuation and
do argument or returnvalue passing. Just use one of these functions as
delegate.c does.
To which I respond:
I *am* using Parrot_run_meth_fromc_args, just like delegate.c does.
Now you tell me, Just invoke it.
But I need to do more than that.  I need to do what 
Parrot_run_meth_fromc_args is attempting to do (i.e., create a return 
continuation and do argument or returnvalue passing.), but correctly.

- Sam Ruby


Re: runops_args vs NCI

2004-12-17 Thread Leopold Toetsch
Sam Ruby wrote:
But I need to do more than that.  I need to do what 
Parrot_run_meth_fromc_args is attempting to do (i.e., create a return 
continuation and do argument or returnvalue passing.), but correctly.
1) runops_fromc and friends are running *opcodes*, nothing else
2) the functions are working, nothing needs fixing here.
I've already stated several times: let's adjust Parrot's method dispatch 
and overloaded method signatures, so that it's directly usable for 
target languages. When that is done, you can get rid of all the 
additional dispatch functions.

- Sam Ruby
leo


Re: runops_args vs NCI

2004-12-17 Thread Leopold Toetsch
Sam Ruby wrote:
I have a number of cases (filter, map, reduce), where I am passed an 
arbirary sub and need to call it.  I should not have to know how the sub 
is implemented.
I'd a look at map and friends now. You are running code that has a 
signature of PP. You'd need additionally:

  if (func-vtable-base_type == enum_class_NCI) {
 typedef PMC* (*func_pp)(Interp*, PMC*);
 func_pp cfunc = (func_pp) D2FPTR(PMC_struct_val(func));
 item = (cfunc)(interpreter, item);
  }
  else { ...
You could of course add a general call_PP wrapper that handles both 
cases. But as you did already replace the general runops_args with a 
hand-crafted call setup, adding above lines should do it.

leo


Re: runops_args vs NCI

2004-12-17 Thread Sam Ruby
Leopold Toetsch wrote:
Sam Ruby wrote:
But I need to do more than that.  I need to do what 
Parrot_run_meth_fromc_args is attempting to do (i.e., create a return 
continuation and do argument or returnvalue passing.), but correctly.
1) runops_fromc and friends are running *opcodes*, nothing else
2) the functions are working, nothing needs fixing here.
I've made a clone of these functions, and made the relevant fixes to my 
copy.  Hopefully someday this will get refactored back into Parrot.

For the record, in the test case I provided, I was calling 
Parrot_run_meth_fromc_args twice.  The first time with a real Sub.  One 
implemented with opcodes.  Or, as you prefer to say it, *opcodes*.  It 
was this call that did not restore the context interpreter-ctx.bp.  As 
near as I can tell, this path is identical to the usage in 
classes/delegate.c.  In other words, it is an accident waiting to happen.

Take a look at Parrot_PyClass_runops_fromc.  If you do, you will see 
that I am only restoring the value of interpreter-ctx.bp if dest is 
non-zero.  Think about it.

The second time I called Parrot_run_meth_fromc_args, it was with an NCI 
method.  The only problem is that in this call, the parameters were set 
into registers after the invoke call.  I believe it to be customary to 
set the parameters into registers prior to the invoke call.  In fact, I 
have logic in PyFunc.pmc (again which is used to invoke Python functions 
which are implemented in opcodes, er, I mean *opcodes*), which depends 
on things happening in this order in order to handle defaults and varargs.

I've already stated several times: let's adjust Parrot's method dispatch 
and overloaded method signatures, so that it's directly usable for 
target languages. When that is done, you can get rid of all the 
additional dispatch functions.
I am not interested in discussing this any more.
The current Parrot has bugs.  I've notified you of a number of them. 
You are apparently not interested as you would prefer to rewrite Parrot 
instead.  Undoubtably, at that time it will have a different set of 
bugs.  At which point, undoubtably, the process will repeat.

Onward.
- Sam Ruby


Re: runops_args vs NCI

2004-12-17 Thread Leopold Toetsch
Sam Ruby wrote:
I've made a clone of these functions, and made the relevant fixes to my 
copy.
As you said, that's your time. You can clone half of Parrot core for 
experiments.

Hopefully someday this will get refactored back into Parrot.
The code for running PASM/PIR code is fine.
The second time I called Parrot_run_meth_fromc_args, it was with an NCI 
method.  The only problem is ...
... that you are calling the wrong function during your handrolled and 
unneeded redispatch. Why are you are creating a return continuation for 
calling a C function? Why do you pass registers according to pdd03 to a 
C function? Why do you execute a C function with a new context structure?

*runops_args* is running *opcodes*. A NCI fuction is a thin wrapper 
around a piece of C code.

I am not interested in discussing this any more.
Sam, it's a big difficult to tell you that the current approach of 
implementing Python will not work, because as soon as I say so, you 
gonna stop discussing necessary issues.

The current Parrot has bugs.  I've notified you of a number of them.
Sure - And, yes, thanks your notice I've fixed one today.
... You 
are apparently not interested as you would prefer to rewrite Parrot 
instead.
Make it workable. Complete. Which admittedly needs some rewrite, yes. 
Such is life.

 Undoubtably, at that time it will have a different set of 
bugs.  At which point, undoubtably, the process will repeat.
No, there are of course no bugs in Parrot final, never ;)
Onward.
- Sam Ruby
leo


runops_args vs NCI

2004-12-16 Thread Sam Ruby
pseudo-code for runops_args:
  runops_args(PMC* sub, char* sig, va_list ap) {
dest = VTABLE_invoke(interpreter, sub, NULL);
REG_*[*] = ap[*], as appropriate
if (dest) runops
  }
However, VTABLE_invoke on NCI methods is where the real work is done 
(including reading from and writing to registers), and a null dest is 
returned.

The net effect is that if you try to invoke a NCI with a signature of 
PP, the NCI method will be called with whatever happens to be in 
PMC_REG(5) at the time, and what it returns will be overwritten with 
your first argument.

Is there a reason why the invoke couldn't be done immediately prior to 
the call to runops?

- Sam Ruby