Ticket #787 (new todo)

Opened 5 years ago

Last modified 5 years ago

add vtables for: get_pmc_keyed{_int,_str,}_lvalue ; and similarly for slice

Reported by: japhb Owned by:
Priority: normal Milestone:
Component: core Version: 1.3.0
Severity: medium Keywords:
Cc: Language:
Patch status: Platform: all

Description

See discussion starting at:

 http://irclog.perlgeek.de/parrot/2009-06-23#i_1260446

In short, HLLs expect to be able to bind to an element (or slice) of a collection as an lvalue, even if that collection is implemented as a packed array of non-PMCs underneath the covers. Indexing into a collection for rvalue return and for lvalue return are different operations; thus we need lvalue variants of get_pmc_keyed* to go along with the current rvalue variants, and the HLLs need to use the correct variant for the operation they wish to perform.

Change History

  Changed 5 years ago by jkeenan

  • platform set to all
  • component changed from none to core

in reply to: ↑ description   Changed 5 years ago by pmichaud

I agree that Parrot needs some additional support for lvalues -- I've remarked on this in previous #parrot and #parrotsketch conversations but we've never come down to making changes.

So, I agree that what Parrot provides is currently insufficient.

However, part of the problem is that from an HLL perspective Parrot really confuses the notions of "binding" and "assignment", and this specific approach to resolving the problem seems to perpetuate that confusion even further. We should hold some more (non-Trac) discussions about the issues, either on #parrot or the mailing list.

Pm

follow-up: ↓ 5   Changed 5 years ago by allison

Parrot doesn't need to have a vtable entry for every HLL operation. This one unpacks pretty cleanly to a series of opcodes (fetch the element/slice, assign to it, store it back). This ticket rejected, but agreed that we need to have a more general conversation about lvalue support, assignment, and binding.

  Changed 5 years ago by pmichaud

See my proposal for "fetch" and "vivify" opcodes at TT #1138.

Pm

in reply to: ↑ 3   Changed 5 years ago by pmichaud

Replying to allison:

Parrot doesn't need to have a vtable entry for every HLL operation. This one unpacks pretty cleanly to a series of opcodes (fetch the element/slice, assign to it, store it back).

This response is at the least very misleading, so I'll try to clarify things a bit here.

To assign to an element of an aggregate, the basic sequence is "fetch the element PMC, assign to it". There's no "store it back" operation -- the PMC element retrieved by the fetch is still bound in the aggregate, so assigning a new value to that PMC effectively changes it in the aggregate. In code, the basic sequence would be:

    $P0 = aggregate[key]
    assign $P0, value

The tricky part is when someone wants to assign to an element of an aggregate that doesn't already exist. In this case, "fetch the element" returns NULL, so a new PMC has to be created and bound into the aggregate (i.e., vivified):

    ##  HLL: @aggregate[$key] = $value
    $P0 = aggregate[key]
    unless null $P0 goto vivified
    $P0 = new ['Undef']
    aggregate[key] = $P0
  vivified:
    assign $P0, value

For a non-vivifying fetch of an element, we still want to avoid the NULL that comes back from the aggregate but we don't want to make it permanent, so we get:

    ##  HLL:  say @aggregate[$key]
    $P0 = aggregate[key]
    unless null $P0 goto vivified
    $P0 = new ['Undef']
  vivified:
    say $P0

I think this is what the original posting was getting at -- there are vivifying (lvalue) and non-vivifying (rvalue) forms of "fetch an element", and Parrot's opcodes, vtables, and built-in types don't really support the distinction well. We can potentially improve things with specialized opcodes, proxy elements in aggregates, and/or references (Rakudo ends up doing all three of these) -- the question is whether any of them belong in "core Parrot" to provide a common interface that can be shared by all HLLs.

TT #1138 posits the creation of a "vivify" opcode to address the "rvalue fetch" problem, but it doesn't address the issue of "lvalue fetch".

Pm

[update: I've since proposed separate "fetch" and "vivify" opcodes for generic rvalue and lvalue fetch -- see TT #1138.]

Note: See TracTickets for help on using tickets.