Go to the first, previous, next, last section, table of contents.

assembler after

Function: assembleAfter { label asm -> }
file: job.t
package: muf
status: alpha

The assembleAfter prim is a specialized hack supporting the MUF after{ ... }alwaysDo{ ... } construct -- and matching constructs in other languages.

We implement after{ ... }alwaysDo{ ... } as follows:

assembleLabelGet  -> label1
assembleLabelGet  -> label2
label1 asm assembleAfter                    ( Push a PROTECTFRAME )
...                                      ( Protected code clause )
label2 asm assembleAlwaysDo                ( Convert frame to VANILLA )
label1 asm assembleLabel                    ( Label matching AFTER )
...                                      ( Mandatory code clause )
label2 a assembleLabel                      ( Label end of clause )
.lib.muf.popUnwindframe a assembleCall     ( Pop VANILLA frame. )

This is internally the most complex of the control structures to implement, and what can actually happen gets somewhat involved.

For example, if a throw is executed in the protected first clause, it must be interrupted long enough for the second clause to be executed, and then resumed at the end of the second clause.

This is implemented by pushing an appropriate frame on the loop stack as a flag before beginning execution of the second clause; popUnwindframe then checks the frame on top of the loopstack when it executes: if it finds a VANILLA frame, it merely pops it and lets execution continue; if it finds a special flag frame, it pops it and continues the interrupted operation, whatever it was.

Additional complexities arise if the protected clause contains fork operations, since the second clause must still be executed exactly once (not exactly once per job).

However, the above boilerplate sequence is all one needs to know as an in-db compiler writer in order to implement the construct.

Go to the first, previous, next, last section, table of contents.