loop unrolling and completion values in ES6

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Apr 6 00:08:01 UTC 2015


Alan,

I freed up  goa couple minutes for a quick look at this.  I want to spend some more time look at it deeper as this is an area where I made some fixes just a couple weeks ago and I want to review them again to make sure everything is as intended.

But, for now a quick answer to your question is:  yes there is an intentional difference.

For blocks that are not part of loops (and top level StatementLists) we wanted to preserve the legacy completion values described in the NOTE at the end of 13.1.13.  this requires preserving empty completion values originating from stand-alone blocks.  However, we also wanted all control flow statements to always produce a non-emptry completion value.

Allen

On Apr 3, 2015, at 10:32 AM, Alan Schmitt wrote:

> Hello,
> 
> I've been looking into completions records in ES6, and I have a question
> regarding loop unrolling, as it seems completion records are dealt with
> differently for breaks inside loops and breaks inside blocks.
> 
> For while loops, the spec says (this is the part that applies to
> a "break" in the statement, as in that case LoopContinues is false):
> 
> e. Let stmt be the result of evaluating Statement.
> f. If LoopContinues (stmt, labelSet) is false, return Completion(stmt).
> 
> For blocks, the spec says:
> 
> StatementList : StatementList StatementListItem
> 
> 1. Let sl be the result of evaluating StatementList.
> 2. ReturnIfAbrupt(sl).
> 3. Let s be the result of evaluating StatementListItem.
> 4. If s.[[type]] is throw, return Completion(s).
> 5. If s.[[value]] is empty, let V = sl.[[value]], otherwise let V = s.[[value]].
> 6. Return Completion{[[type]]: s.[[type]], [[value]]: V, [[target]]: s.[[target]]}.
> 
> The difference between the two is the following: if there is a "break"
> carrying the empty completion value in a while statement, then it is
> returned as such. For blocks, the completion value is patched with the
> current value (V in the algorithm above).
> 
> According to the spec, the following code has a completion value of
> 1 (the completion record of the while is (break,empty,a), it gets
> patched to (break,1,a) in the inner block, and the labeled statement
> return (normal, 1,empty) which is also the final completion record).
> 
> #+begin_src javascript
> var c;
> a: {
>  c=1;
>  while(true){
>    if (c)
>      c=0;
>    else
>      break a;
>  }
> }
> #+end_src
> 
> 
> If we unroll one iteration of the loop, we get this code:
> 
> #+begin_src javascript
> var c;
> a: {
>  c=1;
>  if (true) {
>    if (c)
>      c=0;
>    else
>      break a;
>    while(true){
>      if (c)
>        c=0;
>      else
>        break a;
>    }
>  }
> }
> #+end_src
> 
> Now the completion record is (normal,0,empty): since the assignment
> "c=0" is run outside the while loop, the value 0 gets patched in the
> completion record, so the 1 is not patched in.
> 
> Is there a motivation for this difference of completion values between
> while loops and blocks?
> 
> Thanks,
> 
> Alan
> 
> -- 
> OpenPGP Key ID : 040D0A3B4ED2E5C7
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss



More information about the es-discuss mailing list