Stop Spam Harvesters, Join Project Honey Pot

I finally found a flexible way to represent scope information in the Language::P intermediate representation.

The newly added scope_enter and scope_leave pseudo-instructions mark the start/end of a scope boundary; both instructions have a single ‘scope’ attribute that links to scope information stored in the IR code object. The advantage of this solution over storing scope start/end offsets directly in the scope information is that it works across IR code transformations and when scope entry/exit are on separate basic blocks; the disadvantage is that finding the start/end of a scope requires scanning all the IR representation of a subroutine.

For example the following (dummy) Perl code

{
    1;
}

compiles to

# main
L1:
  scope_enter scope=0   # implicit scope for the file
  jump to=L2
L2:
  scope_enter scope=1   # scope delimited by the braces
  constant_integer value=1
  scope_leave scope=1
  jump to=L4
L4:
  scope_leave scope=0
  end

Scope information contains the outer scope (or -1 for a subroutine/main scope), flags to indicate the scope type (subroutine, eval, main) and the bytecode to be run when exiting the scope through an exception.

In the DLR runtime, wrapping subroutines/evals with a try/catch block containing the scope exit code for inner scopes should be (almost) all is needed for stack unwinding.

The implementation for the Toy runtime (just pushed to GitHub) is straightforward: when an exception is thrown, search the scope list for the scope containing the current program counter and walk up the scope list, running scope exit bytecode, until an eval scope is found.