Dan Sugalski <[EMAIL PROTECTED]> wrote:
> At 11:45 AM +0200 10/29/04, Leopold Toetsch wrote:

>>Should the traceback object be avaiable as a PMC?

> Nah, I don't think so. There's nothing in the traceback that wouldn't
> be in the current continuation, so I don't think it's worth
> bothering.

Ok. This sounds like the traceback object *is* the continuation ;)

What about:

  $P0 = interpinfo .INTERPINFO_CURRENT_CONT  # implemented already

  printerr $P0    # does $P0->vtable->getstring(), which creates
                  # a traceback string, maybe verbosity depending
                  # on debug settings

OTOH having get_string the whole traceback chain isn't really good for
overriding it. So maybe it should return just the info for the current
call.

> Basically we want to be able to walk a continuation chain and get
> access to everything.

Ok. E.g.

    .local pmc caller, cont
    cont = $P0
  tb_loop:
    caller = cont."caller"()
    unless caller goto tb_end
    cont   = caller."continuation"()
    printerr cont
    goto tb_loop
  tb_end:

I think having methods is ok for that. It's in no way time critical to
warrant opcodes.

>>What information should be included in the traceback (object)?

> Everything. It seems to me that there are two big things people will
> do with traceback info.

When and in which run loop do we update the C<current_pc>[1] ? Only,
when warnings are enabled or always?

It's not quite clear from the C<invoke Px> opcode, whether we are
calling a subroutine, or returning from a subroutine. So the place to
update the current program counter of the current call can only be in
the Sub PMC. The Sub PMC's invoke() vtable is called with the C<void
*next> opcode pointer following the call. [2]

Now as we have C<invoke> and C<invoke Px> it would need some code
inspection to decide if the call had one or two opcodes. That's all a
bit ugly and time consuming.

> 1) Dumps of call chains and state
> 2) Evil parent environment twiddling

> For #1 we'll want to be able to walk up the chain and yank out
> sub/method names, the object being method-called, the lexical pads in
> effect, the namespace as it stands, and suchlike stuff.

Ok.

> (I'm told
> that Python has a very nice verbose dump such that when it dumps you
> get not only the call tree but the variables and their values, which
> strikes me as good in two ways -- it makes debugging easier and it
> makes those sorts of errors harder to ignore because the output's so
> damn big)

The traceback printed e.g. after an exception just prints caller
locations. But the traceback object itself has some read-only
atrributes. Amongst others, C<tb_frame> let you inspect the call frame's
variables.

> For #2, which includes doing things like upvar and other
> unpleasantness, we'll be taking advantage of the fact that while we
> can't necessarily touch the actual interpreter/continuation chain,
> anything we fetch out of it (like, say, the lexical scope) is
> touchable, so injecting variables into your caller's scope isn't a
> big deal.

What for is that needed? Well, if the lexical scope PMC is available by
introspection, you can of course add variables to it, with all the
consequences that *might* arise from such hacks.

> Dunno if we want to have a PMC that has this Evil Knowledge, or if we
> want to have ops. Part of me leans towards an op or two -- if for no
> other reason then to force it to be very explicit in any language
> that does it, which will make people think and make it really tough
> to do accidentally.

Methods ought to be explicit enough.

leo

[1] we had C<cur_pc> in the interpreter structure. It's now
C<current_pc> in the context.

[2] except for overriden methods, which are called from C

Reply via email to