+ proper exception object cleanup when using break, continue or exit in try

except blocks in WebAssembly native exceptions mode
This commit is contained in:
Nikolay Nikolov 2021-10-05 07:41:42 +03:00
parent ddbdc529b1
commit 99ab6bd56d

View File

@ -451,9 +451,22 @@ implementation
destroytemps,
excepttemps: tcgexceptionstatehandler.texceptiontemps;
afteronflowcontrol: tflowcontrol;
oldCurrExitLabel,
oldContinueLabel,
oldBreakLabel: tasmlabel;
oldLoopContBr: integer;
oldLoopBreakBr: integer;
oldExitBr: integer;
in_loop: Boolean;
label
errorexit;
begin
oldCurrExitLabel:=nil;
oldContinueLabel:=nil;
oldBreakLabel:=nil;
oldLoopContBr:=0;
oldLoopBreakBr:=0;
oldExitBr:=0;
location_reset(location,LOC_VOID,OS_NO);
doobjectdestroyandreraisestate:=Default(tcgexceptionstatehandler.texceptionstate);
@ -463,8 +476,8 @@ implementation
reference_reset(excepttemps.jmpbuf,0,[]);
reference_reset(excepttemps.reasonbuf,0,[]);
//exceptstate.oldflowcontrol:=flowcontrol;
//flowcontrol:=[fc_inflowcontrol,fc_catching_exceptions];
in_loop:=assigned(current_procinfo.CurrBreakLabel);
cexceptionstatehandler.new_exception(current_asmdata.CurrAsmList,excepttemps,tek_except,trystate);
current_asmdata.CurrAsmList.concat(taicpu.op_none(a_try));
@ -475,8 +488,6 @@ implementation
if codegenerror then
goto errorexit;
//exceptionstate.newflowcontrol:=flowcontrol;
//flowcontrol:=exceptionstate.oldflowcontrol;
cexceptionstatehandler.end_try_block(current_asmdata.CurrAsmList,tek_except,excepttemps,trystate,nil);
current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_catch,current_asmdata.WeakRefAsmSymbol(FPC_EXCEPTION_TAG_SYM,AT_WASM_EXCEPTION_TAG)));
@ -521,9 +532,82 @@ implementation
current_asmdata.CurrAsmList.concat(taicpu.op_none(a_try));
thlcgwasm(hlcg).incblock;
{ the 'exit' block }
current_asmdata.CurrAsmList.concat(taicpu.op_none(a_block));
thlcgwasm(hlcg).incblock;
oldCurrExitLabel:=current_procinfo.CurrExitLabel;
oldExitBr:=thlcgwasm(hlcg).exitBr;
current_asmdata.getjumplabel(current_procinfo.CurrExitLabel);
thlcgwasm(hlcg).exitBr:=thlcgwasm(hlcg).br_blocks;
{ the 'break' block }
current_asmdata.CurrAsmList.concat(taicpu.op_none(a_block));
thlcgwasm(hlcg).incblock;
if in_loop then
begin
oldBreakLabel:=current_procinfo.CurrBreakLabel;
oldLoopBreakBr:=thlcgwasm(hlcg).loopBreakBr;
current_asmdata.getjumplabel(current_procinfo.CurrBreakLabel);
thlcgwasm(hlcg).loopBreakBr:=thlcgwasm(hlcg).br_blocks;
end;
{ the 'continue' block }
current_asmdata.CurrAsmList.concat(taicpu.op_none(a_block));
thlcgwasm(hlcg).incblock;
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;
end;
secondpass(t1);
cexceptionstatehandler.end_try_block(current_asmdata.CurrAsmList,tek_except,destroytemps,doobjectdestroyandreraisestate,nil);
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_doneexception',[],nil).resetiftemp;
current_asmdata.CurrAsmList.concat(taicpu.op_const(a_br,4));
{ exit the 'continue' block }
current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block));
thlcgwasm(hlcg).decblock;
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));
end;
{ exit the 'break' block }
current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block)); // break
thlcgwasm(hlcg).decblock;
if fc_break 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-oldLoopBreakBr));
end;
{ exit the 'exit' block }
current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_block)); // exit
thlcgwasm(hlcg).decblock;
if fc_exit 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-oldExitBr));
end;
current_procinfo.CurrExitLabel:=oldCurrExitLabel;
thlcgwasm(hlcg).exitBr:=oldExitBr;
if in_loop then
begin
current_procinfo.CurrContinueLabel:=oldContinueLabel;
thlcgwasm(hlcg).loopContBr:=oldLoopContBr;
current_procinfo.CurrBreakLabel:=oldBreakLabel;
thlcgwasm(hlcg).loopBreakBr:=oldLoopBreakBr;
end;
current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_catch,current_asmdata.WeakRefAsmSymbol(FPC_EXCEPTION_TAG_SYM,AT_WASM_EXCEPTION_TAG)));