The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Subs - Parrot Subroutines

DESCRIPTION

Parrot comes with different subroutine and alike classes which implement CPS (Continuation Passing Style) and PCC (Parrot Calling Conventions) docs/pdds/pdd03_calling_conventions.pod.

Class Tree

  Sub
    Closure
      Continuation
        Coroutine
      Eval
      RetContinuation

Items in the Subs Context

  Subtype       Controlstack    PadStack   UserStack  Warnings
  ------------------------------------------------------------
  Sub                -             -           -         C
  Closure            -             C           -         C
  Continuation       C             C           C         C
  Coroutine          C             C           C         C
  RetContinuation    X             X           X         X

  "C" ... COWed copy is in context
  "X" ... is in context
  "-" ... isn't.

SYNOPSIS

Creation

Create a subroutine of class Sub and assign the subroutine address to it:

  new P0, .Sub
  set_addr I0, _sub_label
  set P0, I0

This can be done with one opcode:

  newsub P0, .Sub, _sub_label

Create a subroutine (in P0) and a return continuation (in P1):

  newsub .Sub, .RetContinuation, _sub_label, ret_label

Invocation i.e. calling the sub

  invoke        # call the subroutine in P0 (P1 was created earlier)

  invokecc      # call sub in P0 and create return continuation in P1

Returning from a sub

  invoke P1     # call return continuation in P1

All together now

The following scheme can be used if a subroutine is called once or if performance doesn't matter:

    newsub P0, .Sub, _sub_label # create subroutine
    set I5, 42                  # pass an argument
    invokecc                    # create ret continuation and call sub
    end                         # fin.
  _sub_label:
    print I5                    # do something with parameters
    invoke P1                   # return

If a subroutine is called several times, for instance inside a loop, the creation of the return continuation can be done outside the loop if performance is an issue:

    newsub .Sub, .RetContinuation, _sub_label, ret_label
    set I16, 1000000
    set I17, 0
  lp:
    pushtopi            # preserve counter vars
    invoke
  ret_label:
    poptopi
    inc I17
    lt I17, I16, lp
    end
  _sub_label:
    # do_something
    invoke P1

If items in the interpreter context are changed between creation of the subroutine/return continuation and its invocation, the updatecc opcode should be used, so that the state of the return continuation matches that of the interpreter:

    newsub .Sub, .RetContinuation, _sub_label, ret_label
    ...
    warningson 1
    ...
    updatecc
    invoke
    ...

FILES

classes/sub.pmc, classes/closure.pmc, classes/continuation.pmc, classes/coroutine.pmc, sub.c, t/pmc/sub.t

SEE ALSO

docs/pdds/pdd03_calling_conventions.pod languages/imcc/docs/calling_conventions.pod

AUTHOR

Leopold Toetsch <lt@toetsch.at>