@@ -1200,11 +1200,16 @@ class JSGenerator {
12001200 } else if ( blockType === BlockType . CONDITIONAL || blockType === BlockType . LOOP ) {
12011201 const branchVariable = this . localVariables . next ( ) ;
12021202 this . source += `const ${ branchVariable } = createBranchInfo(${ blockType === BlockType . LOOP } );\n` ;
1203- this . source += `while (${ branchVariable } .branch = +(${ this . generateCompatibilityLayerCall ( node , false , branchVariable ) } )) {\n` ;
1203+ this . source += `while (! ${ branchVariable } .escaped || ( ${ branchVariable } . branch = +(${ this . generateCompatibilityLayerCall ( node , false , branchVariable ) } ) )) {\n` ;
12041204 this . source += `switch (${ branchVariable } .branch) {\n` ;
1205+ this . compatBranchInfo = { node, branchVar : branchVariable , escaped : false } ;
12051206 for ( let i = 0 ; i < node . substacks . length ; i ++ ) {
12061207 this . source += `case ${ i + 1 } : {\n` ;
12071208 this . descendStack ( node . substacks [ i ] , new Frame ( false ) ) ;
1209+ if ( this . compatBranchInfo . escaped ) {
1210+ this . source += `}\n` ; // close break point
1211+ this . compatBranchInfo . escaped = false ;
1212+ }
12081213 this . source += `break;\n` ;
12091214 this . source += `}\n` ; // close case
12101215 }
@@ -1213,6 +1218,7 @@ class JSGenerator {
12131218 this . source += `if (!${ branchVariable } .isLoop) break;\n` ;
12141219 this . yieldLoop ( ) ;
12151220 this . source += '}\n' ; // close while
1221+ this . compatBranchInfo = undefined ;
12161222 } else {
12171223 throw new Error ( `Unknown block type: ${ blockType } ` ) ;
12181224 }
@@ -1306,7 +1312,13 @@ class JSGenerator {
13061312 if ( inLoop ) this . source += `break;\n` ;
13071313 else {
13081314 // this could be an uncompiled loop block
1309- this . source += `yield* executeInCompatibilityLayer({}, runtime.getOpcodeFunction("control_exitLoop"), false, false, "${ node . id } ", null);\n` ;
1315+ if ( this . compatBranchInfo ) {
1316+ this . compatBranchInfo . escaped = true ;
1317+ this . source += `${ this . compatBranchInfo . branchVar } .escaped = true;\n` ;
1318+ this . source += `if (false) {\n` ; // stop following code in the stack
1319+ } else {
1320+ this . source += `yield* executeInCompatibilityLayer({}, runtime.getOpcodeFunction("control_exitLoop"), false, false, "${ node . id } ", null);\n` ;
1321+ }
13101322 }
13111323 break ;
13121324 }
@@ -1315,7 +1327,13 @@ class JSGenerator {
13151327 if ( inLoop ) this . source += `continue;\n` ;
13161328 else {
13171329 // this could be an uncompiled loop block
1318- this . source += `yield* executeInCompatibilityLayer({}, runtime.getOpcodeFunction("control_exitLoop"), false, false, "${ node . id } ", null);\n` ;
1330+ if ( this . compatBranchInfo ) {
1331+ // we only need to make the loop stop stack code, not end the loop
1332+ this . compatBranchInfo . escaped = true ;
1333+ this . source += `if (false) {\n` ; // stop following code in the stack
1334+ } else {
1335+ this . source += `yield* executeInCompatibilityLayer({}, runtime.getOpcodeFunction("control_exitLoop"), false, false, "${ node . id } ", null);\n` ;
1336+ }
13191337 }
13201338 break ;
13211339 }
0 commit comments