[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]

Re: [PATCH pod/perlmod.pod 5.005_63] Special Blocks For Less Than Gurus



Here are the four kinds of out-of-sequence, "sub"-keyword--optional
functions (which now don't quite count as functions for things like
shift and pop defaulting to @_ rather than @ARGV):

    BEGIN - run ASAP (as soon as parsable) [or FIFO, if you would]
    STOP  - run at the end of compilation in LIFO order
    INIT  - run at the beginning of execution in FIFO order
    END   - run at the end of execution in LIFO order

And here is how I like to think of the phases of your program's life:

    I.      Compilation Phase 
    II.     Code Generation Phase (optional)
    III.    Parse Tree Reconstruction Phase (optional)
    IV.     Execution Phase 

+----------------------+
| I. Compilation Phase |
+----------------------+

  1. Compiler converts source code into parse trees, during which time:

       a. BEGIN blocks are executed now, as soon as they're seen
          (essentially FIFO order); this also includes "use" and "no"
          statements.
       b. STOP, INIT, and END blocks are scheduled by the compiler for
          delayed execution.

  2. Compiler finishes with your source code.  Note that any eval {BLOCK},
     s///e constructs, and constant regular expressions are compiled here,
     not later.

  3. All delayed STOP blocks are now executed, in LIFO order.

+---------------------------+
| II. Code Generation Phase |
+---------------------------+

    (optional; if present, follows compiler)

Code generator converts compiled state from previous phase into one of these
two forms:

  1. C code by using the perlcc script, which then calls cc to
     produce a native a.out in one of two fashions, depending on
     which one of the two possible kinds of C code has been select.

     a. One form simply reconstructs the parse tree and runs it
        using the usual runops() loop that perl itself uses.  This 
	is the regular perlcc mode.

     b. The other generates a linearized and optimized C equivalent
        of the runtime code path (which resembles a giant jump
        table) and executes that.  This is run using `perlcc -opt'.

    For lack of better words, the canonical names for these backends
    are "Simple C Backend" and "Optimized C Backend".

  2. Perl bytecode by using the `perlcc -b' tool (née perlbc), which
     uses the perl bytecode front-end to produce a script which
     when run will triggers the Parse Tree Reconstruction Phase.

+--------------------------------------+
| III. Parse Tree Reconstruction Phase |
+--------------------------------------+

    (optional; if present, precedes interpreter)

  1. If input to the is Perl bytecode, first reassemble parse trees from
     that bytecode.

  2. Technically, this is something of a trick using the ByteLoader module.
     It is triggered by scripts containing code like this (probably
     produced by perlbc in previous optional phase)

	 #!/usr/bin/perl
	 use ByteLoader 0.03;
	 [byte code here]

+---------------------+
| IV. Execution Phase |
+---------------------+

Interpreter takes parse trees and executes them:

  1. All delayed INIT blocks are first executed in FIFO order.

  2. The main program is run, and terminates.  Note that an eval
     STRING, any do or require statements, a s///ee construct, or
     regexes containing variable portions with code-assertions while
     the use re 'eval' pragma is enabled will all require a callback
     from the interpreter back into the compiler.

  3. All delayed END blocks are finally executed, but in LIFO order.
     (Compiler-generated output does not execute END blocks currently,
     but that's just a bug about to be fixed real soon now.)


Follow-Ups from:
Michael G Schwern <schwern@pobox.com>

[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]