rfc:loop_default

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
rfc:loop_default [2014/09/19 07:59] – created leighrfc:loop_default [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 26: Line 26:
 } }
  
-for ($i = 0, $j = $k; $i < 4 && $j < 65536; $i++, $j >>= 1) {+for ($i = 0, $j = $k; $i < 4 && $j < 65536; $i++, $j <<= 1) {
  // loop body  // loop body
 } }
Line 41: Line 41:
 </code> </code>
  
 +In the case of ''for'' and ''foreach'' loops it's immediately obvious that separate tracking variables would be required to monitor whether the loop had been entered. This proposal does away with that necessity and increases performance as a side-effect.
  
-This kind of behaviour has been suggested before using the ''else'' keyword, however ''else'' has several drawbacks:+''do {} while();'' loops have been deliberately excluded from this behaviour as they always enter the loop at least once. The only available behaviour for a ''default'' block on a do while loop is to have it execute if the loop only iterates once, which feels inconsistent.
  
-Not backwards compatible by default due to dangling ''else''+Alternate syntax loops also gain this functionality with a ''default:'' clause that does not break ''switch'' statements. 
 + 
 +This type of behaviour has been suggested before usually using the ''else'' keyword, however using ''else'' has several drawbacks that make ''default'' more attractive: 
 + 
 + Not backwards compatible by default due to dangling ''else''
 <code php> <code php>
 if ($something) if ($something)
Line 53: Line 58:
 </code> </code>
  
-Making it backwards compatible leads to inconsistent behaviour+ Making it backwards compatible leads to inconsistent behaviour
 <code php> <code php>
 if ($something) if ($something)
Line 62: Line 67:
 </code> </code>
  
-It breaks familiarity with similar behaviour in other languages+ It breaks familiarity with similar behaviour in other languages
 <code php> <code php>
 while ($cond) { while ($cond) {
Line 76: Line 81:
 The intention is to implement this by duplicating loop prologues to avoid the requirement for tracking variables, and keep performance on-par with pre-patch looping. The intention is to implement this by duplicating loop prologues to avoid the requirement for tracking variables, and keep performance on-par with pre-patch looping.
  
-Pre-patch basic while loop.+As an example here is the opcode dump of a pre-patch basic while loop.
 <code> <code>
 +$i = 3;
 +while ($i--) {
 +    print 'loop';
 +}
 +
 line     # *  op                           fetch          ext  return  operands line     # *  op                           fetch          ext  return  operands
 --------------------------------------------------------------------------------- ---------------------------------------------------------------------------------
Line 89: Line 99:
 </code> </code>
  
-Post-patch basic while loop with default block (labels added to help visualise flow)+And a post-patch basic while loop with default block (labels added to help visualise flow)
 <code> <code>
 +$i = 0;
 +while ($i--) {
 +    print 'loop';
 +}
 +default {
 +    print 'default';
 +}
 +
          # *  op                           fetch          ext  return  operands          # *  op                           fetch          ext  return  operands
 --------------------------------------------------------------------------------- ---------------------------------------------------------------------------------
-          >   ASSIGN                                                   !0, 3+          >   ASSIGN                                                   !0, 0
 cond_1:  1  >   POST_DEC                                         ~1      !0 cond_1:  1  >   POST_DEC                                         ~1      !0
             > JMPZNZ                                   loop            ~1, ->default             > JMPZNZ                                   loop            ~1, ->default
Line 106: Line 124:
 </code> </code>
  
-The key here is that ''cond_1'' uses JMPZNZ to jump straight to ''loop'' on the first iteration, but ''cond_2'' is used for all iterations subsequently.+The key here is that ''cond_1'' uses JMPZNZ to either jump over ''cond_2'' straight to ''loop'' or to the ''default'' block on the first iteration, but after the loop is entered ''cond_2'' is used for all subsequent iterations and jumps to ''nxt_op'' on failure, skipping the ''default'' block. ''for'' and ''foreach'' loops are handled in a similar manner.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 131: Line 149:
  
 Both require the loop to be entered to have an effect, which means the default block cannot be executed at the point these constructs are used. Both require the loop to be entered to have an effect, which means the default block cannot be executed at the point these constructs are used.
- 
-Alternate syntax loops also continue to function as expected with a ''default:'' clause that does not alter ''switch'' statements. 
  
 Loops without bodies also get to have default blocks Loops without bodies also get to have default blocks
Line 143: Line 159:
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
-A proof of concept is being worked on by Leigh+A proof of concept is being worked on by Leigh - ''while'' and ''for'' are working - ''foreach'' currently segfaulting
  
 ===== Implementation ===== ===== Implementation =====
rfc/loop_default.1411113578.txt.gz · Last modified: 2017/09/22 13:28 (external edit)