Parcourir la source

+ introduced the use of asm labels for WebAssembly. Resolve them in
tcpuprocinfo.postprocess_code. Use them when generating code for the
'continue' label jumps.

Nikolay Nikolov il y a 3 ans
Parent
commit
01dc62b127
4 fichiers modifiés avec 199 ajouts et 63 suppressions
  1. 6 0
      compiler/aasmbase.pas
  2. 119 0
      compiler/wasm32/cpupi.pas
  3. 1 4
      compiler/wasm32/hlcgcpu.pas
  4. 73 59
      compiler/wasm32/nwasmflw.pas

+ 6 - 0
compiler/aasmbase.pas

@@ -196,6 +196,9 @@ interface
            TAsmList with loadsym/loadref/const_symbol (PFV) }
          refs       : longint;
        public
+{$ifdef wasm}
+         nestingdepth : longint;
+{$endif wasm}
          { on avr the compiler needs to replace cond. jumps with too large offsets
            so we have to store an offset somewhere to calculate jump distances }
 {$ifdef AVR}
@@ -337,6 +340,9 @@ implementation
         typ:=_typ;
         { used to remove unused labels from the al_procedures }
         refs:=0;
+{$ifdef wasm}
+        nestingdepth:=-1;
+{$endif wasm}
       end;
 
 

+ 119 - 0
compiler/wasm32/cpupi.pas

@@ -379,6 +379,123 @@ implementation
             end;
         end;
 
+      procedure resolve_labels_pass1(asmlist: TAsmList);
+        var
+          hp: tai;
+          lastinstr: taicpu;
+          cur_nesting_depth: longint;
+          lbl: tai_label;
+        begin
+          cur_nesting_depth:=0;
+          lastinstr:=nil;
+          hp:=tai(asmlist.first);
+          while assigned(hp) do
+            begin
+              case hp.typ of
+                ait_instruction:
+                  begin
+                    lastinstr:=taicpu(hp);
+                    case lastinstr.opcode of
+                      a_block,
+                      a_loop,
+                      a_if,
+                      a_try:
+                        inc(cur_nesting_depth);
+
+                      a_end_block,
+                      a_end_loop,
+                      a_end_if,
+                      a_end_try:
+                        begin
+                          dec(cur_nesting_depth);
+                          if cur_nesting_depth<0 then
+                            internalerror(2021102001);
+                        end;
+                    end;
+                  end;
+                ait_label:
+                  begin
+                    lbl:=tai_label(hp);
+                    lbl.labsym.nestingdepth:=-1;
+                    if assigned(lastinstr) then
+                      begin
+                        if lastinstr.opcode=a_loop then
+                          lbl.labsym.nestingdepth:=cur_nesting_depth
+                        else if lastinstr.opcode in [a_end_block,a_end_try,a_end_if] then
+                          lbl.labsym.nestingdepth:=cur_nesting_depth+1;
+                      end;
+                  end;
+              end;
+              hp:=tai(hp.Next);
+            end;
+          if cur_nesting_depth<>0 then
+            internalerror(2021102002);
+        end;
+
+      procedure resolve_labels_pass2(asmlist: TAsmList);
+        var
+          hp: tai;
+          instr: taicpu;
+          cur_nesting_depth: longint;
+        begin
+          cur_nesting_depth:=0;
+          hp:=tai(asmlist.first);
+          while assigned(hp) do
+            begin
+              if hp.typ=ait_instruction then
+                begin
+                  instr:=taicpu(hp);
+                  case instr.opcode of
+                    a_block,
+                    a_loop,
+                    a_if,
+                    a_try:
+                      inc(cur_nesting_depth);
+
+                    a_end_block,
+                    a_end_loop,
+                    a_end_if,
+                    a_end_try:
+                      begin
+                        dec(cur_nesting_depth);
+                        if cur_nesting_depth<0 then
+                          internalerror(2021102003);
+                      end;
+
+                    a_br,
+                    a_br_if:
+                      begin
+                        if instr.ops<>1 then
+                          internalerror(2021102004);
+                        if instr.oper[0]^.typ=top_ref then
+                          begin
+                            if not assigned(instr.oper[0]^.ref^.symbol) then
+                              internalerror(2021102005);
+                            if (instr.oper[0]^.ref^.base<>NR_NO) or
+                               (instr.oper[0]^.ref^.index<>NR_NO) or
+                               (instr.oper[0]^.ref^.offset<>0) then
+                              internalerror(2021102006);
+                            if instr.oper[0]^.ref^.symbol.nestingdepth=-1 then
+                              internalerror(2021102007);
+                            instr.loadconst(0,cur_nesting_depth-instr.oper[0]^.ref^.symbol.nestingdepth);
+                          end;
+                      end;
+                  end;
+                end;
+              hp:=tai(hp.Next);
+            end;
+          if cur_nesting_depth<>0 then
+            internalerror(2021102008);
+        end;
+
+      procedure resolve_labels(asmlist: TAsmList);
+        begin
+          if not assigned(asmlist) then
+            exit;
+          resolve_labels_pass1(asmlist);
+          resolve_labels_pass2(asmlist);
+        end;
+
       var
        templist : TAsmList;
        l : TWasmLocal;
@@ -404,6 +521,8 @@ implementation
 
         replace_local_frame_pointer(aktproccode);
 
+        resolve_labels(aktproccode);
+
         inherited postprocess_code;
       end;
 

+ 1 - 4
compiler/wasm32/hlcgcpu.pas

@@ -56,9 +56,6 @@ uses
       function is_methodptr_like_type(d:tdef): boolean;
      public
       br_blocks: integer;
-      loopContBr: integer; // the value is different depending of the condition test
-                           // if it's in the beggning the jump should be done to the loop (1)
-                           // if the condition at the end, the jump should done to the end of block (0)
       loopBreakBr: integer;
       exitBr: integer;
       raiseBr: integer;  // raiseBr is only used in branchful exceptions mode (ts_wasm_bf_exceptions)
@@ -1804,7 +1801,7 @@ implementation
       if l=current_procinfo.CurrBreakLabel then
         list.concat(taicpu.op_const(a_br,br_blocks-loopBreakBr))
       else if l=current_procinfo.CurrContinueLabel then
-        list.concat(taicpu.op_const(a_br,br_blocks-loopContBr))
+        list.concat(taicpu.op_sym(a_br,l))
       else if l=current_procinfo.CurrExitLabel then
         list.concat(taicpu.op_const(a_br,br_blocks-exitBr))
       else

+ 73 - 59
compiler/wasm32/nwasmflw.pas

@@ -131,7 +131,6 @@ implementation
          oldclabel,oldblabel : tasmlabel;
          truelabel,falselabel : tasmlabel;
          oldflowcontrol : tflowcontrol;
-         oldloopcontbroffset: Integer;
          oldloopbreakbroffset: Integer;
       begin
         location_reset(location,LOC_VOID,OS_NO);
@@ -142,7 +141,6 @@ implementation
 
         oldflowcontrol:=flowcontrol;
 
-        oldloopcontbroffset:=thlcgwasm(hlcg).loopContBr;
         oldloopbreakbroffset:=thlcgwasm(hlcg).loopBreakBr;
         oldclabel:=current_procinfo.CurrContinueLabel;
         oldblabel:=current_procinfo.CurrBreakLabel;
@@ -158,10 +156,9 @@ implementation
 
         if lnf_testatbegin in loopflags then
         begin
+          hlcg.a_label(current_asmdata.CurrAsmList,lcont);
           pass_generate_code_condition;
-          thlcgwasm(hlcg).loopContBr:=thlcgwasm(hlcg).br_blocks;
-        end else
-          thlcgwasm(hlcg).loopContBr:=thlcgwasm(hlcg).br_blocks+1;
+        end;
 
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_block));
         thlcgwasm(hlcg).incblock;
@@ -176,9 +173,11 @@ implementation
 
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block));
         thlcgwasm(hlcg).decblock;
-        if not (lnf_testatbegin in loopflags) then begin
-          pass_generate_code_condition;
-        end;
+        if not (lnf_testatbegin in loopflags) then
+          begin
+            hlcg.a_label(current_asmdata.CurrAsmList,lcont);
+            pass_generate_code_condition;
+          end;
         current_asmdata.CurrAsmList.concat(taicpu.op_const(a_br,0) ); // jump back to loop
 
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_loop));
@@ -188,7 +187,6 @@ implementation
 
         current_procinfo.CurrContinueLabel:=oldclabel;
         current_procinfo.CurrBreakLabel:=oldblabel;
-        thlcgwasm(hlcg).loopContBr:=oldloopcontbroffset;
         thlcgwasm(hlcg).loopBreakBr:=oldloopbreakbroffset;
 
         { a break/continue in a while/repeat block can't be seen outside }
@@ -453,8 +451,7 @@ implementation
         afteronflowcontrol: tflowcontrol;
         oldCurrExitLabel,
         oldContinueLabel,
-        oldBreakLabel: tasmlabel;
-        oldLoopContBr: integer;
+        oldBreakLabel, NewContinueLabel: tasmlabel;
         oldLoopBreakBr: integer;
         oldExitBr: integer;
         in_loop: Boolean;
@@ -464,7 +461,6 @@ implementation
         oldCurrExitLabel:=nil;
         oldContinueLabel:=nil;
         oldBreakLabel:=nil;
-        oldLoopContBr:=0;
         oldLoopBreakBr:=0;
         oldExitBr:=0;
         location_reset(location,LOC_VOID,OS_NO);
@@ -560,9 +556,8 @@ implementation
                 if in_loop then
                   begin
                     oldContinueLabel:=current_procinfo.CurrContinueLabel;
-                    oldLoopContBr:=thlcgwasm(hlcg).loopContBr;
-                    current_asmdata.getjumplabel(current_procinfo.CurrContinueLabel);
-                    thlcgwasm(hlcg).loopContBr:=thlcgwasm(hlcg).br_blocks;
+                    current_asmdata.getjumplabel(NewContinueLabel);
+                    current_procinfo.CurrContinueLabel:=NewContinueLabel;
                   end;
 
                 secondpass(t1);
@@ -575,10 +570,12 @@ implementation
                 { exit the 'continue' block }
                 current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block));
                 thlcgwasm(hlcg).decblock;
+                if in_loop then
+                  hlcg.a_label(current_asmdata.CurrAsmList,NewContinueLabel);
                 if fc_continue in doobjectdestroyandreraisestate.newflowcontrol then
                   begin
                     hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_doneexception',[],nil).resetiftemp;
-                    current_asmdata.CurrAsmList.concat(taicpu.op_const(a_br,thlcgwasm(hlcg).br_blocks-oldLoopContBr));
+                    current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_br,oldContinueLabel));
                   end;
 
                 { exit the 'break' block }
@@ -604,7 +601,6 @@ implementation
                 if in_loop then
                   begin
                     current_procinfo.CurrContinueLabel:=oldContinueLabel;
-                    thlcgwasm(hlcg).loopContBr:=oldLoopContBr;
                     current_procinfo.CurrBreakLabel:=oldBreakLabel;
                     thlcgwasm(hlcg).loopBreakBr:=oldLoopBreakBr;
                   end;
@@ -645,8 +641,7 @@ implementation
         afteronflowcontrol: tflowcontrol;
         oldCurrExitLabel,
         oldContinueLabel,
-        oldBreakLabel: tasmlabel;
-        oldLoopContBr: integer;
+        oldBreakLabel, NewContinueLabel: tasmlabel;
         oldLoopBreakBr: integer;
         oldExitBr: integer;
         oldRaiseBr: Integer;
@@ -657,7 +652,6 @@ implementation
         oldCurrExitLabel:=nil;
         oldContinueLabel:=nil;
         oldBreakLabel:=nil;
-        oldLoopContBr:=0;
         oldLoopBreakBr:=0;
         oldExitBr:=0;
         oldRaiseBr:=0;
@@ -769,9 +763,8 @@ implementation
                 if in_loop then
                   begin
                     oldContinueLabel:=current_procinfo.CurrContinueLabel;
-                    oldLoopContBr:=thlcgwasm(hlcg).loopContBr;
-                    current_asmdata.getjumplabel(current_procinfo.CurrContinueLabel);
-                    thlcgwasm(hlcg).loopContBr:=thlcgwasm(hlcg).br_blocks;
+                    current_asmdata.getjumplabel(NewContinueLabel);
+                    current_procinfo.CurrContinueLabel:=NewContinueLabel;
                   end;
 
                 secondpass(t1);
@@ -784,10 +777,12 @@ implementation
                 { exit the 'continue' block }
                 current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block));
                 thlcgwasm(hlcg).decblock;
+                if in_loop then
+                  hlcg.a_label(current_asmdata.CurrAsmList,NewContinueLabel);
                 if fc_continue in doobjectdestroyandreraisestate.newflowcontrol then
                   begin
                     hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_doneexception',[],nil).resetiftemp;
-                    current_asmdata.CurrAsmList.concat(taicpu.op_const(a_br,thlcgwasm(hlcg).br_blocks-oldLoopContBr));
+                    current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_br,OldContinueLabel));
                   end;
 
                 { exit the 'break' block }
@@ -816,7 +811,6 @@ implementation
                 if in_loop then
                   begin
                     current_procinfo.CurrContinueLabel:=oldContinueLabel;
-                    thlcgwasm(hlcg).loopContBr:=oldLoopContBr;
                     current_procinfo.CurrBreakLabel:=oldBreakLabel;
                     thlcgwasm(hlcg).loopBreakBr:=oldLoopBreakBr;
                   end;
@@ -878,7 +872,6 @@ implementation
         oldCurrExitLabel,
         oldContinueLabel,
         oldBreakLabel: tasmlabel;
-        oldLoopContBr: integer;
         oldLoopBreakBr: integer;
         oldExitBr: integer;
         finallyexceptionstate: tcgexceptionstatehandler.texceptionstate;
@@ -897,6 +890,17 @@ implementation
             thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
           end;
 
+        procedure generate_exceptreason_check_br(reason: tcgint; l: TAsmLabel);
+          var
+            reasonreg : tregister;
+          begin
+            reasonreg:=hlcg.getintregister(current_asmdata.CurrAsmList,exceptionreasontype);
+            hlcg.g_exception_reason_load(current_asmdata.CurrAsmList,exceptionreasontype,exceptionreasontype,excepttemps.reasonbuf,reasonreg);
+            thlcgwasm(hlcg).a_cmp_const_reg_stack(current_asmdata.CurrAsmList,exceptionreasontype,OC_EQ,reason,reasonreg);
+            current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_br_if,l));
+            thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
+          end;
+
       begin
         location_reset(location,LOC_VOID,OS_NO);
         oldBreakLabel:=nil;
@@ -904,7 +908,6 @@ implementation
         continuefinallylabel:=nil;
         breakfinallylabel:=nil;
         oldLoopBreakBr:=0;
-        oldLoopContBr:=0;
 
         in_loop:=assigned(current_procinfo.CurrBreakLabel);
 
@@ -957,10 +960,8 @@ implementation
         if in_loop then
           begin
             oldContinueLabel:=current_procinfo.CurrContinueLabel;
-            oldLoopContBr:=thlcgwasm(hlcg).loopContBr;
             continuefinallylabel:=get_jump_out_of_try_finally_frame_label(finallyexceptionstate);
             current_procinfo.CurrContinueLabel:=continuefinallylabel;
-            thlcgwasm(hlcg).loopContBr:=thlcgwasm(hlcg).br_blocks;
           end;
 
         { try code }
@@ -983,6 +984,8 @@ implementation
         { exit the 'continue' block }
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block));
         thlcgwasm(hlcg).decblock;
+        if in_loop then
+          hlcg.a_label(current_asmdata.CurrAsmList,continuefinallylabel);
         { exceptionreason:=4 (continue) }
         hlcg.g_exception_reason_save_const(current_asmdata.CurrAsmList,exceptionreasontype,4,excepttemps.reasonbuf);
         current_asmdata.CurrAsmList.concat(taicpu.op_const(a_br,2)); // jump to the 'finally' section
@@ -1029,7 +1032,7 @@ implementation
         if fc_break in finallyexceptionstate.newflowcontrol then
           generate_exceptreason_check_br(3,thlcgwasm(hlcg).br_blocks-oldLoopBreakBr);
         if fc_continue in finallyexceptionstate.newflowcontrol then
-          generate_exceptreason_check_br(4,thlcgwasm(hlcg).br_blocks-oldLoopContBr);
+          generate_exceptreason_check_br(4,oldContinueLabel);
 
         cexceptionstatehandler.unget_exception_temps(current_asmdata.CurrAsmList,excepttemps);
 
@@ -1041,7 +1044,6 @@ implementation
         if assigned(current_procinfo.CurrBreakLabel) then
          begin
            current_procinfo.CurrContinueLabel:=oldContinueLabel;
-           thlcgwasm(hlcg).loopContBr:=oldLoopContBr;
            current_procinfo.CurrBreakLabel:=oldBreakLabel;
            thlcgwasm(hlcg).loopBreakBr:=oldLoopBreakBr;
          end;
@@ -1061,7 +1063,6 @@ implementation
         oldCurrExitLabel,
         oldContinueLabel,
         oldBreakLabel: tasmlabel;
-        oldLoopContBr: integer;
         oldLoopBreakBr: integer;
         oldExitBr: integer;
         finallyexceptionstate: tcgexceptionstatehandler.texceptionstate;
@@ -1080,6 +1081,17 @@ implementation
           thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
         end;
 
+      procedure generate_exceptreason_check_br(reason: tcgint; l: tasmlabel);
+        var
+          reasonreg : tregister;
+        begin
+          reasonreg:=hlcg.getintregister(current_asmdata.CurrAsmList,exceptionreasontype);
+          hlcg.g_exception_reason_load(current_asmdata.CurrAsmList,exceptionreasontype,exceptionreasontype,excepttemps.reasonbuf,reasonreg);
+          thlcgwasm(hlcg).a_cmp_const_reg_stack(current_asmdata.CurrAsmList,exceptionreasontype,OC_EQ,reason,reasonreg);
+          current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_br_if,l));
+          thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
+        end;
+
       procedure generate_exceptreason_throw(reason: tcgint);
         var
           reasonreg : tregister;
@@ -1102,7 +1114,6 @@ implementation
         continuefinallylabel:=nil;
         breakfinallylabel:=nil;
         oldLoopBreakBr:=0;
-        oldLoopContBr:=0;
 
         in_loop:=assigned(current_procinfo.CurrBreakLabel);
 
@@ -1155,10 +1166,8 @@ implementation
         if in_loop then
           begin
             oldContinueLabel:=current_procinfo.CurrContinueLabel;
-            oldLoopContBr:=thlcgwasm(hlcg).loopContBr;
             continuefinallylabel:=get_jump_out_of_try_finally_frame_label(finallyexceptionstate);
             current_procinfo.CurrContinueLabel:=continuefinallylabel;
-            thlcgwasm(hlcg).loopContBr:=thlcgwasm(hlcg).br_blocks;
           end;
 
         { the inner 'try..end_try' block }
@@ -1194,6 +1203,8 @@ implementation
         { exit the 'continue' block }
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block));
         thlcgwasm(hlcg).decblock;
+        if in_loop then
+          hlcg.a_label(current_asmdata.CurrAsmList,continuefinallylabel);
         { exceptionreason:=4 (continue) }
         hlcg.g_exception_reason_save_const(current_asmdata.CurrAsmList,exceptionreasontype,4,excepttemps.reasonbuf);
         current_asmdata.CurrAsmList.concat(taicpu.op_const(a_br,2)); // jump to the 'finally' section
@@ -1240,7 +1251,7 @@ implementation
         if fc_break in finallyexceptionstate.newflowcontrol then
           generate_exceptreason_check_br(3,thlcgwasm(hlcg).br_blocks-oldLoopBreakBr);
         if fc_continue in finallyexceptionstate.newflowcontrol then
-          generate_exceptreason_check_br(4,thlcgwasm(hlcg).br_blocks-oldLoopContBr);
+          generate_exceptreason_check_br(4,oldContinueLabel);
         generate_exceptreason_throw(1);
 
         cexceptionstatehandler.unget_exception_temps(current_asmdata.CurrAsmList,excepttemps);
@@ -1253,7 +1264,6 @@ implementation
         if assigned(current_procinfo.CurrBreakLabel) then
          begin
            current_procinfo.CurrContinueLabel:=oldContinueLabel;
-           thlcgwasm(hlcg).loopContBr:=oldLoopContBr;
            current_procinfo.CurrBreakLabel:=oldBreakLabel;
            thlcgwasm(hlcg).loopBreakBr:=oldLoopBreakBr;
          end;
@@ -1268,7 +1278,6 @@ implementation
         oldCurrExitLabel,
         oldContinueLabel,
         oldBreakLabel: tasmlabel;
-        oldLoopContBr: integer;
         oldLoopBreakBr: integer;
         oldExitBr: integer;
         oldRaiseBr: integer;
@@ -1288,6 +1297,17 @@ implementation
           thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
         end;
 
+      procedure generate_exceptreason_check_br(reason: tcgint; l: tasmsymbol);
+        var
+          reasonreg : tregister;
+        begin
+          reasonreg:=hlcg.getintregister(current_asmdata.CurrAsmList,exceptionreasontype);
+          hlcg.g_exception_reason_load(current_asmdata.CurrAsmList,exceptionreasontype,exceptionreasontype,excepttemps.reasonbuf,reasonreg);
+          thlcgwasm(hlcg).a_cmp_const_reg_stack(current_asmdata.CurrAsmList,exceptionreasontype,OC_EQ,reason,reasonreg);
+          current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_br_if,l));
+          thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
+        end;
+
       procedure generate_exceptreason_reraise(reason: tcgint);
         var
           reasonreg : tregister;
@@ -1311,7 +1331,6 @@ implementation
         continuefinallylabel:=nil;
         breakfinallylabel:=nil;
         oldLoopBreakBr:=0;
-        oldLoopContBr:=0;
         oldRaiseBr:=0;
 
         in_loop:=assigned(current_procinfo.CurrBreakLabel);
@@ -1365,10 +1384,8 @@ implementation
         if in_loop then
           begin
             oldContinueLabel:=current_procinfo.CurrContinueLabel;
-            oldLoopContBr:=thlcgwasm(hlcg).loopContBr;
             continuefinallylabel:=get_jump_out_of_try_finally_frame_label(finallyexceptionstate);
             current_procinfo.CurrContinueLabel:=continuefinallylabel;
-            thlcgwasm(hlcg).loopContBr:=thlcgwasm(hlcg).br_blocks;
           end;
 
         { the inner 'try..end_try' block }
@@ -1406,6 +1423,8 @@ implementation
         { exit the 'continue' block }
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block));
         thlcgwasm(hlcg).decblock;
+        if in_loop then
+          hlcg.a_label(current_asmdata.CurrAsmList,continuefinallylabel);
         { exceptionreason:=4 (continue) }
         hlcg.g_exception_reason_save_const(current_asmdata.CurrAsmList,exceptionreasontype,4,excepttemps.reasonbuf);
         current_asmdata.CurrAsmList.concat(taicpu.op_const(a_br,2)); // jump to the 'finally' section
@@ -1455,7 +1474,7 @@ implementation
         if fc_break in finallyexceptionstate.newflowcontrol then
           generate_exceptreason_check_br(3,thlcgwasm(hlcg).br_blocks-oldLoopBreakBr);
         if fc_continue in finallyexceptionstate.newflowcontrol then
-          generate_exceptreason_check_br(4,thlcgwasm(hlcg).br_blocks-oldLoopContBr);
+          generate_exceptreason_check_br(4,oldContinueLabel);
         generate_exceptreason_reraise(1);
 
         cexceptionstatehandler.unget_exception_temps(current_asmdata.CurrAsmList,excepttemps);
@@ -1468,7 +1487,6 @@ implementation
         if assigned(current_procinfo.CurrBreakLabel) then
          begin
            current_procinfo.CurrContinueLabel:=oldContinueLabel;
-           thlcgwasm(hlcg).loopContBr:=oldLoopContBr;
            current_procinfo.CurrBreakLabel:=oldBreakLabel;
            thlcgwasm(hlcg).loopBreakBr:=oldLoopBreakBr;
          end;
@@ -1512,8 +1530,7 @@ implementation
         exceptlocreg: tregister;
         oldCurrExitLabel,
         oldContinueLabel,
-        oldBreakLabel: tasmlabel;
-        oldLoopContBr: integer;
+        oldBreakLabel, NewContinueLabel: tasmlabel;
         oldLoopBreakBr: integer;
         oldExitBr: integer;
         in_loop: Boolean;
@@ -1523,7 +1540,6 @@ implementation
         oldCurrExitLabel:=nil;
         oldContinueLabel:=nil;
         oldBreakLabel:=nil;
-        oldLoopContBr:=0;
         oldLoopBreakBr:=0;
         oldExitBr:=0;
         location_reset(location,LOC_VOID,OS_NO);
@@ -1587,9 +1603,8 @@ implementation
         if in_loop then
           begin
             oldContinueLabel:=current_procinfo.CurrContinueLabel;
-            oldLoopContBr:=thlcgwasm(hlcg).loopContBr;
-            current_asmdata.getjumplabel(current_procinfo.CurrContinueLabel);
-            thlcgwasm(hlcg).loopContBr:=thlcgwasm(hlcg).br_blocks;
+            current_asmdata.getjumplabel(NewContinueLabel);
+            current_procinfo.CurrContinueLabel:=NewContinueLabel;
           end;
 
         if assigned(right) then
@@ -1603,10 +1618,12 @@ implementation
         { exit the 'continue' block }
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block));
         thlcgwasm(hlcg).decblock;
+        if in_loop then
+          hlcg.a_label(current_asmdata.CurrAsmList,NewContinueLabel);
         if fc_continue in doobjectdestroyandreraisestate.newflowcontrol then
           begin
             hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_doneexception',[],nil).resetiftemp;
-            current_asmdata.CurrAsmList.concat(taicpu.op_const(a_br,thlcgwasm(hlcg).br_blocks-oldLoopContBr));
+            current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_br,oldContinueLabel));
           end;
 
         { exit the 'break' block }
@@ -1632,7 +1649,6 @@ implementation
         if in_loop then
           begin
             current_procinfo.CurrContinueLabel:=oldContinueLabel;
-            thlcgwasm(hlcg).loopContBr:=oldLoopContBr;
             current_procinfo.CurrBreakLabel:=oldBreakLabel;
             thlcgwasm(hlcg).loopBreakBr:=oldLoopBreakBr;
           end;
@@ -1667,8 +1683,7 @@ implementation
         exceptlocreg: tregister;
         oldCurrExitLabel,
         oldContinueLabel,
-        oldBreakLabel: tasmlabel;
-        oldLoopContBr: integer;
+        oldBreakLabel, NewContinueLabel: tasmlabel;
         oldLoopBreakBr: integer;
         oldExitBr: integer;
         oldRaiseBr: Integer;
@@ -1679,7 +1694,6 @@ implementation
         oldCurrExitLabel:=nil;
         oldContinueLabel:=nil;
         oldBreakLabel:=nil;
-        oldLoopContBr:=0;
         oldLoopBreakBr:=0;
         oldExitBr:=0;
         oldRaiseBr:=0;
@@ -1749,9 +1763,8 @@ implementation
         if in_loop then
           begin
             oldContinueLabel:=current_procinfo.CurrContinueLabel;
-            oldLoopContBr:=thlcgwasm(hlcg).loopContBr;
-            current_asmdata.getjumplabel(current_procinfo.CurrContinueLabel);
-            thlcgwasm(hlcg).loopContBr:=thlcgwasm(hlcg).br_blocks;
+            current_asmdata.getjumplabel(NewContinueLabel);
+            current_procinfo.CurrContinueLabel:=NewContinueLabel;
           end;
 
         if assigned(right) then
@@ -1765,10 +1778,12 @@ implementation
         { exit the 'continue' block }
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block));
         thlcgwasm(hlcg).decblock;
+        if in_loop then
+          hlcg.a_label(current_asmdata.CurrAsmList,NewContinueLabel);
         if fc_continue in doobjectdestroyandreraisestate.newflowcontrol then
           begin
             hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_doneexception',[],nil).resetiftemp;
-            current_asmdata.CurrAsmList.concat(taicpu.op_const(a_br,thlcgwasm(hlcg).br_blocks-oldLoopContBr));
+            current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_br,oldContinueLabel));
           end;
 
         { exit the 'break' block }
@@ -1797,7 +1812,6 @@ implementation
         if in_loop then
           begin
             current_procinfo.CurrContinueLabel:=oldContinueLabel;
-            thlcgwasm(hlcg).loopContBr:=oldLoopContBr;
             current_procinfo.CurrBreakLabel:=oldBreakLabel;
             thlcgwasm(hlcg).loopBreakBr:=oldLoopBreakBr;
           end;