The unroll opcode

An old problem with parrot exception handling is the "inner runloop"
problem. The exception handler can be invoked from parrot code called
from a C function called from parrot code. The C function calls the
parrot code by entering a new runloop. Parrot exceptions are
resumable, and to appropriately resume the inner runloops must be
preserved.

However when resume is not done the code following the handling of the
exception gets executed from a runloop deeper than the original of the
sub that contains the handler, and this lead to failures later in the
program.

In some discussions of this problem it was suggested that a way of
marking "I've finished handling this exception and want to continue
normal flow" will be a way to solve it.

The unroll opcode is an implementation of that idea. It takes an
ExceptionHandler as argument and unroll the inner runloops. As a
convenience, it can also take an Exception argument and look for the
ExceptionHandler on it.

This is an example of usage:

 
.sub main :main 
 push_eh handler 
 maybe_bad() 
 .return() 
handler: 
 .local pmc exception 
 .get_results(exception) 
 unroll exception 
 show_some_message() 
 .return() 
.end 

The only change in the handler code is the addition of unroll at a
point after any possible resume.

Unroll has been added as experimental feature in Parrot 2.4.0

How to build parrot for the Nokia N900

As I said in a recent post, I built parrot with the Maemo SDK and
installed it in the Nokia N900. This is how I do it:

First you need to install the Maemo SDK. I followed the documentation in:
http://wiki.maemo.org/Documentation/Maemo_5_Final_SDK_Installation

I used the scratchbox environment in linux i386. If you use another
platform you may need to adjust some of the following instructions.

You may want to do some testing to verify that the scratchbox is working.

You don't need to worry about the Xephyr part, we are not going to use graphics.

You may need to create a file /etc/osso-at-inf/locale to set the
locale, or leave if empty if the one that the system choose makes perl
warn about unsupported locale each time is invoked (parrot build does
it lots of times).

When all is working, log in to the scratchbox environment, select the
FREEMANTLE_ARMEL target, download parrot trunk and build it:

 
run-standalone bash 
svn checkout https://svn.parrot.org/parrot/trunk parrot 
cd parrot 
perl Configure.pl --prefix=/opt/parrot --optimize 
make 
make install 

Now you have parrot installed in /opt/parrot inside the scratchbox. In
a standard installation this should map to:
/scratchbox/users/your_user_name/targets/FREEMANTLE_ARMEL/opt/parrot

Copy that directory to /opt/parrot on the N900 and you are almost
ready. You can use scp if you install the openssh packages in the
N900.

Now open a terminal session in the N900. Put the parrot bin dir in
your PATH and check that parrot works:

 
PATH=/opt/parrot/bin:$PATH 
parrot -V 

Note that the information about the run platform is wrong. I don't
worked on that yet.

That's all!

Towards PIR compilers in HLL

Parrot is starting to have the features required to write a PIR
compiler in high level languages. The experimental PMCs to introspect
opcodes allow pasm assembly and disassembly, and the packfile PMCs to
read and write the packfile structures from PBC files.

Last days I added the program packfile.winxed to winxed examples
directory, which dumps and disassemble PBCs. Now I've written this
little program that test the generation of a short working PBC:

 
#! winxed 
 
//********************************************************************** 
 
const int OP_end = 0; 
const int OP_noop = 1; 
const int OP_say_sc = 465; 
 
//********************************************************************** 
 
function main() 
{ 
 var packfile = new 'Packfile'; 
 var dir = packfile.get_directory(); 
 say(elements(dir)); 
 
 int cst_hello = 0; 
 int cst_bye = 1; 
 
 var constseg = new 'PackfileConstantTable'; 
 constseg[cst_hello] = 'Hello, world!'; 
 constseg[cst_bye] = 'Bye, world!'; 
 
 var code = new 'PackfileRawSegment'; 
 int of = 0; 
 code[of++] = OP_noop; 
 code[of++] = OP_say_sc; 
 code[of++] = cst_hello; 
 code[of++] = OP_say_sc; 
 code[of++] = cst_bye; 
 code[of++] = OP_end; 
 
 dir['BYTECODE_test.pir'] = code; 
 
 dir['CONSTANT_test.pir'] = constseg; 
 dir['BYTECODE_test.pir_ANN'] = new 'PackfileAnnotations'; 
 dir['FIXUP_test.pir'] = new 'PackfileFixupTable'; 
 say(elements(dir)); 
 
 string rawdata = packfile; 
 say('About to write'); 
 var handle = new 'FileHandle'.open('h.pbc', 'wb'); 
 handle.print(rawdata); 
 handle.close(); 
 say('Bye'); 
} 
 
// That's all folks! 

The pieces are on the board, let's play!