@@ -2391,13 +2391,15 @@ export class Compiler extends DiagnosticEmitter {
23912391 var outerFlow = this . currentFlow ;
23922392
23932393 // (block $break └►┐ flow
2394- // (loop $continue ├◄───────────┐ recompile?
2395- // (body) └─┐ bodyFlow │
2396- // ┌─┘ │
2394+ // (loop $loop ├◄───────────┐ recompile?
2395+ // (?block $continue └─┐ │
2396+ // (body) │ bodyFlow │
2397+ // ) ┌─┘ │
23972398 // ┌◄┼►╢ │ breaks or terminates?
2398- // (local.set $tcond (condition)) │ └─┐ condFlow │
2399+ // │ └─┐ │ but does not continue
2400+ // (br_if (cond) $loop) │ │ condFlow │
23992401 // │ ┌─┘ │
2400- // (br_if (local.get $tcond) $continue) ├◄┴────────────┘ condition?
2402+ // ├◄┴────────────┘ condition?
24012403 // ) └─┐
24022404 // ) ┌─┘
24032405
@@ -2411,6 +2413,7 @@ export class Compiler extends DiagnosticEmitter {
24112413 flow . breakLabel = breakLabel ;
24122414 var continueLabel = "do-continue|" + label ;
24132415 flow . continueLabel = continueLabel ;
2416+ var loopLabel = "do-loop|" + label ;
24142417
24152418 // Compile the body (always executes)
24162419 var bodyFlow = flow . fork ( ) ;
@@ -2424,7 +2427,8 @@ export class Compiler extends DiagnosticEmitter {
24242427 }
24252428
24262429 // Shortcut if body never falls through
2427- if ( bodyFlow . isAny ( FlowFlags . TERMINATES | FlowFlags . BREAKS ) ) {
2430+ var possiblyContinues = bodyFlow . isAny ( FlowFlags . CONTINUES | FlowFlags . CONDITIONALLY_CONTINUES ) ;
2431+ if ( bodyFlow . isAny ( FlowFlags . TERMINATES | FlowFlags . BREAKS ) && ! possiblyContinues ) {
24282432 bodyStmts . push (
24292433 module . unreachable ( )
24302434 ) ;
@@ -2441,6 +2445,12 @@ export class Compiler extends DiagnosticEmitter {
24412445 ) ;
24422446 let condKind = this . evaluateCondition ( condExpr ) ;
24432447
2448+ if ( possiblyContinues ) {
2449+ bodyStmts = [
2450+ module . block ( continueLabel , bodyStmts )
2451+ ] ;
2452+ }
2453+
24442454 // Shortcut if condition is always false
24452455 if ( condKind == ConditionKind . FALSE ) {
24462456 bodyStmts . push (
@@ -2454,21 +2464,16 @@ export class Compiler extends DiagnosticEmitter {
24542464 module . drop ( condExpr )
24552465 ) ;
24562466 bodyStmts . push (
2457- module . br ( continueLabel )
2467+ module . br ( loopLabel )
24582468 ) ;
24592469 flow . set ( FlowFlags . TERMINATES ) ;
24602470
24612471 } else {
2462- let tcond = condFlow . getTempLocal ( Type . bool ) ;
24632472 bodyStmts . push (
2464- module . local_set ( tcond . index , condExpr , false ) // bool
2465- ) ;
2466- bodyStmts . push (
2467- module . br ( continueLabel ,
2468- module . local_get ( tcond . index , TypeRef . I32 )
2473+ module . br ( loopLabel ,
2474+ condExpr
24692475 )
24702476 ) ;
2471- condFlow . freeTempLocal ( tcond ) ;
24722477 flow . inherit ( condFlow ) ;
24732478
24742479 // Detect if local flags are incompatible before and after looping, and
@@ -2488,7 +2493,7 @@ export class Compiler extends DiagnosticEmitter {
24882493 outerFlow . popBreakLabel ( ) ;
24892494 this . currentFlow = outerFlow ;
24902495 var expr = module . block ( breakLabel , [
2491- module . loop ( continueLabel ,
2496+ module . loop ( loopLabel ,
24922497 module . flatten ( bodyStmts )
24932498 )
24942499 ] ) ;
0 commit comments