This patch completes the process of making while, until, ensure,
rescuse, optn, and a few other node purely iterative. A description of
the methodology follows.

while:
When a while loop is encountered, two instructions are immediately
added to the stack: the condition to be evaluated and a check to see
if the condition evaluated true. If it is a do...while loop, nothing
more is added. In the case of a normal while...end loop two additional
instructions are added to the stack: a "redoable" instruction that
acts as a placeholder for redo events fired inside the loop, and the
body of the loop itself.

Example:
while true
  puts "hello"
end

Instruction stack after while node is evaluated:
condition (true) (also marked as "nextable" for next events)
conditionCheck (also marked as "breakable" for break events)

Example:
do
  puts "hello"
while true

Instructions:
body (puts "hello")
redoable (a noop marker instruction plus the above body, so the body
can be redone)
condition (true) (also marked as "nextable" for next events)
conditionCheck (also marked as "breakable" for break events)

The instructions are executed in sequence. Normal execution causes the
conditionCheck to repeatedly push all four instructions back onto the
stack for reevaluation. In the case of other events, the interpreter
steps in:

For break, all instructions are popped up to and including the nearest
"breakable" instruction. Execution will then continue at the
instruction immediately after the loop.

For redo, all instructions up to and including the redoable
instruction are popped, and the loop body (carried in the redo
instruction) is pushed back on the stack.

For next, all instruction up to but not including the nextable
instruction are popped. The next instruction executed is therefore the
condition eval.

This same methodology is used for the other types of nodes.

until:

Same as while, but with a negative condition check and no deferment of
the condition check as in do...while.

rescue:

Up to three instructions are pushed immediately: the rescue node,
marked as a noop "rescuable" instruction, any "else" node, and the
body of the begin associated with the rescue.

Execution proceeds from the body of the begin associated with the
rescue. Any raised exceptions trigger a raise event in the
interpreter. When that happens, all nodes up to and including the
"rescuable" instruction are popped. The rescue information at that
point is used to calculate whether the raised exception is handled. If
so, a "retriable" version of the rescue node and the appropriate
rescue body are pushed onto the stack; execution then continues with
the rescue body, wherein a "retry" event will cause the entire rescue
node to restart. Should the begin body complete without any raised
exceptions, the noop "rescuable" rescue node will be executed (doing
nothing) and execution will continue at the node following the whole
rescue node.

ensure:

Ensure blocks are pushed on to the stack beneath the begin block they
are associated with. They are marked by the interpreter as "ensured"
so when any of the above events (break, next, redo, retry, raise)
cause the interpreter to dig back down the instruction stack, those
ensured instructions will be executed as encountered.

This appears to work 100% with ant test and does not seem to introduce
any new failures or errors into rubicon. However, there are a few
caveats:

for loops are not yet implemented in this fashion, since they actually
are turned into block executions.

The "aggregation" method of building hashes and arrays was found to
have a bug: if an exception is thrown during the aggregation of
values, the aggregate is not cleaned up.

Throw does not correctly cause ensured blocks to fire.

I have marked the latter two items FIXME and will be exploring
solutions for them while cleaning up and refactoring this patch code

- Charlie


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_idv37&alloc_id865&op=click
_______________________________________________
Jruby-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jruby-devel

Reply via email to