From 5a0956d8050eb4f3f54ba0d8b9fad41fea3a09c3 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Wed, 20 Oct 2021 16:20:08 +0300 Subject: [PATCH] * use WebAssembly asm labels for the raise branch instruction in branchful exceptions mode --- compiler/wasm32/cpupi.pas | 13 +++++++++ compiler/wasm32/hlcgcpu.pas | 6 ++-- compiler/wasm32/nwasmflw.pas | 56 +++++++++++++++++++++--------------- 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/compiler/wasm32/cpupi.pas b/compiler/wasm32/cpupi.pas index c0d5dc7c65..666dc0ec6e 100644 --- a/compiler/wasm32/cpupi.pas +++ b/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; diff --git a/compiler/wasm32/hlcgcpu.pas b/compiler/wasm32/hlcgcpu.pas index 654a512943..4ccd3bbf4f 100644 --- a/compiler/wasm32/hlcgcpu.pas +++ b/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; diff --git a/compiler/wasm32/nwasmflw.pas b/compiler/wasm32/nwasmflw.pas index 0e38411fc2..0d56c821af 100644 --- a/compiler/wasm32/nwasmflw.pas +++ b/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;