Browse Source

* use WebAssembly asm labels for the raise branch instruction in branchful
exceptions mode

Nikolay Nikolov 3 years ago
parent
commit
5a0956d805
3 changed files with 48 additions and 27 deletions
  1. 13 0
      compiler/wasm32/cpupi.pas
  2. 2 4
      compiler/wasm32/hlcgcpu.pas
  3. 33 23
      compiler/wasm32/nwasmflw.pas

+ 13 - 0
compiler/wasm32/cpupi.pas

@@ -36,6 +36,10 @@ interface
 
     tcpuprocinfo=class(tcgprocinfo)
     public
+      { label to the nearest local exception handler }
+      CurrRaiseLabel : tasmlabel;
+
+      constructor create(aparent: tprocinfo); override;
       function calc_stackframe_size : longint;override;
       procedure setup_eh; override;
       procedure generate_exit_label(list: tasmlist); override;
@@ -317,6 +321,13 @@ implementation
                            tcpuprocinfo
 *****************************************************************************}
 
+    constructor tcpuprocinfo.create(aparent: tprocinfo);
+      begin
+        inherited create(aparent);
+        if ts_wasm_bf_exceptions in current_settings.targetswitches then
+          current_asmdata.getjumplabel(CurrRaiseLabel);
+      end;
+
     function tcpuprocinfo.calc_stackframe_size: longint;
       begin
         { the stack frame in WebAssembly should always have a 16-byte alignment }
@@ -342,6 +353,8 @@ implementation
         list.concat(taicpu.op_none(a_end_block));
         thlcgwasm(hlcg).decblock;
         inherited generate_exit_label(list);
+        if ts_wasm_bf_exceptions in current_settings.targetswitches then
+          hlcg.a_label(list,CurrRaiseLabel);
       end;
 
     procedure tcpuprocinfo.postprocess_code;

+ 2 - 4
compiler/wasm32/hlcgcpu.pas

@@ -56,7 +56,6 @@ uses
       function is_methodptr_like_type(d:tdef): boolean;
      public
       br_blocks: integer;
-      raiseBr: integer;  // raiseBr is only used in branchful exceptions mode (ts_wasm_bf_exceptions)
       fntypelookup : TWasmProcTypeLookup;
 
       constructor create;
@@ -257,7 +256,7 @@ implementation
 
   uses
     verbose,cutils,globals,fmodule,constexp,
-    defutil,
+    defutil,cpupi,
     aasmtai,aasmcpu,
     symtable,symcpu,
     procinfo,cpuinfo,cgcpu,tgobj,tgcpu,paramgr;
@@ -2192,7 +2191,6 @@ implementation
       inherited;
       list.concat(taicpu.op_none(a_block));
       incblock;
-      raiseBr:=br_blocks;
     end;
 
   procedure thlcgwasm.gen_exit_code(list: TAsmList);
@@ -2282,7 +2280,7 @@ implementation
 
           decstack(current_asmdata.CurrAsmList,1);
 
-          list.concat(taicpu.op_const(a_br_if,br_blocks-raiseBr));
+          list.concat(taicpu.op_sym(a_br_if,tcpuprocinfo(current_procinfo).CurrRaiseLabel));
       end;
     end;
 

+ 33 - 23
compiler/wasm32/nwasmflw.pas

@@ -102,7 +102,7 @@ implementation
       verbose,globals,systems,globtype,constexp,
       symconst,symdef,symsym,symtype,aasmtai,aasmdata,aasmcpu,defutil,defcmp,
       procinfo,cgbase,cgexcept,pass_1,pass_2,parabase,compinnr,
-      cpubase,cpuinfo,
+      cpubase,cpuinfo,cpupi,
       nbas,nld,ncon,ncnv,ncal,ninl,nmem,nadd,nutils,
       tgobj,paramgr,
       cgutils,hlcgobj,hlcgcpu;
@@ -634,21 +634,22 @@ implementation
         destroytemps,
         excepttemps: tcgexceptionstatehandler.texceptiontemps;
         afteronflowcontrol: tflowcontrol;
+        oldCurrRaiseLabel,
         oldCurrExitLabel,
         oldContinueLabel,
         oldBreakLabel, NewContinueLabel, NewBreakLabel,
-        NewCurrExitLabel: tasmlabel;
-        oldRaiseBr: Integer;
+        NewCurrExitLabel, NewCurrRaiseLabel: tasmlabel;
         in_loop: Boolean;
       label
         errorexit;
       begin
+        oldCurrRaiseLabel:=nil;
         oldCurrExitLabel:=nil;
         oldContinueLabel:=nil;
         oldBreakLabel:=nil;
-        oldRaiseBr:=0;
         NewContinueLabel:=nil;
         NewBreakLabel:=nil;
+        NewCurrRaiseLabel:=nil;
         location_reset(location,LOC_VOID,OS_NO);
         doobjectdestroyandreraisestate:=Default(tcgexceptionstatehandler.texceptionstate);
 
@@ -667,8 +668,9 @@ implementation
 
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_block));
         thlcgwasm(hlcg).incblock;
-        oldRaiseBr:=thlcgwasm(hlcg).raiseBr;
-        thlcgwasm(hlcg).raiseBr:=thlcgwasm(hlcg).br_blocks;
+        oldCurrRaiseLabel:=tcpuprocinfo(current_procinfo).CurrRaiseLabel;
+        current_asmdata.getjumplabel(NewCurrRaiseLabel);
+        tcpuprocinfo(current_procinfo).CurrRaiseLabel:=NewCurrRaiseLabel;
 
         { try block }
         secondpass(left);
@@ -680,9 +682,10 @@ implementation
         current_asmdata.CurrAsmList.concat(taicpu.op_const(a_br,1));
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block));
         thlcgwasm(hlcg).decblock;
+        hlcg.a_label(current_asmdata.CurrAsmList,NewCurrRaiseLabel);
 
         hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_clear_exception_flag',[],nil).resetiftemp;
-        thlcgwasm(hlcg).raiseBr:=oldRaiseBr;
+        tcpuprocinfo(current_procinfo).CurrRaiseLabel:=OldCurrRaiseLabel;
 
         flowcontrol:=[fc_inflowcontrol]+trystate.oldflowcontrol*[fc_catching_exceptions];
         { on statements }
@@ -726,8 +729,9 @@ implementation
 
                 current_asmdata.CurrAsmList.concat(taicpu.op_none(a_block));
                 thlcgwasm(hlcg).incblock;
-                oldRaiseBr:=thlcgwasm(hlcg).raiseBr;
-                thlcgwasm(hlcg).raiseBr:=thlcgwasm(hlcg).br_blocks;
+                oldCurrRaiseLabel:=tcpuprocinfo(current_procinfo).CurrRaiseLabel;
+                current_asmdata.getjumplabel(NewCurrRaiseLabel);
+                tcpuprocinfo(current_procinfo).CurrRaiseLabel:=NewCurrRaiseLabel;
 
                 { the 'exit' block }
                 current_asmdata.CurrAsmList.concat(taicpu.op_none(a_block));
@@ -800,6 +804,7 @@ implementation
 
                 current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block));
                 thlcgwasm(hlcg).decblock;
+                hlcg.a_label(current_asmdata.CurrAsmList,NewCurrRaiseLabel);
 
                 current_procinfo.CurrExitLabel:=oldCurrExitLabel;
                 if in_loop then
@@ -807,7 +812,7 @@ implementation
                     current_procinfo.CurrContinueLabel:=oldContinueLabel;
                     current_procinfo.CurrBreakLabel:=oldBreakLabel;
                   end;
-                thlcgwasm(hlcg).raiseBr:=oldRaiseBr;
+                tcpuprocinfo(current_procinfo).CurrRaiseLabel:=OldCurrRaiseLabel;
 
                 hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_clear_exception_flag',[],nil).resetiftemp;
                 hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_raise_nested',[],nil).resetiftemp;
@@ -836,7 +841,7 @@ implementation
         { return all used control flow statements }
         flowcontrol:=trystate.oldflowcontrol+(doobjectdestroyandreraisestate.newflowcontrol +
           trystate.newflowcontrol - [fc_inflowcontrol,fc_catching_exceptions]);
-        thlcgwasm(hlcg).raiseBr:=oldRaiseBr;
+        tcpuprocinfo(current_procinfo).CurrRaiseLabel:=OldCurrRaiseLabel;
       end;
 
     procedure twasmtryexceptnode.pass_generate_code;
@@ -1253,13 +1258,14 @@ implementation
 
     procedure twasmtryfinallynode.pass_generate_code_bf_exceptions;
       var
+        raisefinallylabel,
         exitfinallylabel,
         continuefinallylabel,
         breakfinallylabel,
+        oldCurrRaiseLabel,
         oldCurrExitLabel,
         oldContinueLabel,
         oldBreakLabel: tasmlabel;
-        oldRaiseBr: integer;
         finallyexceptionstate: tcgexceptionstatehandler.texceptionstate;
         excepttemps : tcgexceptionstatehandler.texceptiontemps;
         exceptframekind: tcgexceptionstatehandler.texceptframekind;
@@ -1305,11 +1311,11 @@ implementation
 
       begin
         location_reset(location,LOC_VOID,OS_NO);
+        oldCurrRaiseLabel:=nil;
         oldBreakLabel:=nil;
         oldContinueLabel:=nil;
         continuefinallylabel:=nil;
         breakfinallylabel:=nil;
-        oldRaiseBr:=0;
 
         in_loop:=assigned(current_procinfo.CurrBreakLabel);
 
@@ -1365,8 +1371,9 @@ implementation
         { the inner 'try..end_try' block }
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_block));
         thlcgwasm(hlcg).incblock;
-        oldRaiseBr:=thlcgwasm(hlcg).raiseBr;
-        thlcgwasm(hlcg).raiseBr:=thlcgwasm(hlcg).br_blocks;
+        oldCurrRaiseLabel:=tcpuprocinfo(current_procinfo).CurrRaiseLabel;
+        current_asmdata.getjumplabel(raisefinallylabel);
+        tcpuprocinfo(current_procinfo).CurrRaiseLabel:=raisefinallylabel;
 
         { try code }
         if assigned(left) then
@@ -1388,6 +1395,7 @@ implementation
         { exit the inner 'try..end_try' block }
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block));
         thlcgwasm(hlcg).decblock;
+        hlcg.a_label(current_asmdata.CurrAsmList,raisefinallylabel);
 
         { exceptionreason:=1 (exception) }
         hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_clear_exception_flag',[],nil).resetiftemp;
@@ -1427,8 +1435,7 @@ implementation
         { end cleanup }
         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoEnd));
 
-        { restore previous raiseBr }
-        thlcgwasm(hlcg).raiseBr:=oldRaiseBr;
+        tcpuprocinfo(current_procinfo).CurrRaiseLabel:=oldCurrRaiseLabel;
 
         { finally code (don't unconditionally set fc_inflowcontrol, since the
           finally code is unconditionally executed; we do have to filter out
@@ -1654,19 +1661,20 @@ implementation
         exceptvarsym : tlocalvarsym;
         exceptlocdef: tdef;
         exceptlocreg: tregister;
+        oldCurrRaiseLabel,
         oldCurrExitLabel,
         oldContinueLabel,
         oldBreakLabel, NewContinueLabel, NewBreakLabel,
-        NewCurrExitLabel: tasmlabel;
-        oldRaiseBr: Integer;
+        NewCurrRaiseLabel, NewCurrExitLabel: tasmlabel;
         in_loop: Boolean;
         doobjectdestroyandreraisestate: tcgexceptionstatehandler.texceptionstate;
         excepttemps: tcgexceptionstatehandler.texceptiontemps;
       begin
+        oldCurrRaiseLabel:=nil;
         oldCurrExitLabel:=nil;
         oldContinueLabel:=nil;
         oldBreakLabel:=nil;
-        oldRaiseBr:=0;
+        NewCurrRaiseLabel:=nil;
         NewBreakLabel:=nil;
         NewContinueLabel:=nil;
         location_reset(location,LOC_VOID,OS_NO);
@@ -1704,8 +1712,9 @@ implementation
 
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_block));
         thlcgwasm(hlcg).incblock;
-        oldRaiseBr:=thlcgwasm(hlcg).raiseBr;
-        thlcgwasm(hlcg).raiseBr:=thlcgwasm(hlcg).br_blocks;
+        oldCurrRaiseLabel:=tcpuprocinfo(current_procinfo).CurrRaiseLabel;
+        current_asmdata.getjumplabel(NewCurrRaiseLabel);
+        tcpuprocinfo(current_procinfo).CurrRaiseLabel:=NewCurrRaiseLabel;
 
         { the 'exit' block }
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_block));
@@ -1779,6 +1788,7 @@ implementation
 
         current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block));
         thlcgwasm(hlcg).decblock;
+        hlcg.a_label(current_asmdata.CurrAsmList,NewCurrRaiseLabel);
 
         current_procinfo.CurrExitLabel:=oldCurrExitLabel;
         if in_loop then
@@ -1786,7 +1796,7 @@ implementation
             current_procinfo.CurrContinueLabel:=oldContinueLabel;
             current_procinfo.CurrBreakLabel:=oldBreakLabel;
           end;
-        thlcgwasm(hlcg).raiseBr:=oldRaiseBr;
+        tcpuprocinfo(current_procinfo).CurrRaiseLabel:=oldCurrRaiseLabel;
 
         hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_clear_exception_flag',[],nil).resetiftemp;
         hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_raise_nested',[],nil).resetiftemp;