+ initial implementation of try..except..end in wasm native exceptions mode.

The 'on' statements are not implemented yet.
This commit is contained in:
Nikolay Nikolov 2021-09-28 20:23:27 +03:00
parent 93b3315691
commit f2abce7ea5

View File

@ -88,7 +88,7 @@ implementation
symconst,symdef,symsym,aasmtai,aasmdata,aasmcpu,defutil,defcmp,
procinfo,cgbase,cgexcept,pass_1,pass_2,parabase,compinnr,
cpubase,cpuinfo,
nbas,nld,ncon,ncnv,ncal,ninl,nmem,nadd,
nbas,nld,ncon,ncnv,ncal,ninl,nmem,nadd,nutils,
tgobj,paramgr,
cgutils,hlcgobj,hlcgcpu;
@ -365,9 +365,109 @@ implementation
end;
procedure twasmtryexceptnode.pass_generate_code_native_exceptions;
var
trystate,doobjectdestroyandreraisestate: tcgexceptionstatehandler.texceptionstate;
destroytemps,
excepttemps: tcgexceptionstatehandler.texceptiontemps;
afteronflowcontrol: tflowcontrol;
label
errorexit;
begin
location_reset(location,LOC_VOID,OS_NO);
{ Exception temps? We don't need no stinking exception temps! :) }
fillchar(excepttemps,sizeof(excepttemps),0);
reference_reset(excepttemps.envbuf,0,[]);
reference_reset(excepttemps.jmpbuf,0,[]);
reference_reset(excepttemps.reasonbuf,0,[]);
//exceptstate.oldflowcontrol:=flowcontrol;
//flowcontrol:=[fc_inflowcontrol,fc_catching_exceptions];
cexceptionstatehandler.new_exception(current_asmdata.CurrAsmList,excepttemps,tek_except,trystate);
current_asmdata.CurrAsmList.concat(taicpu.op_none(a_try));
thlcgwasm(hlcg).incblock;
{ try block }
secondpass(left);
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)));
flowcontrol:=[fc_inflowcontrol]+trystate.oldflowcontrol*[fc_catching_exceptions];
{ on statements }
//if assigned(right) then
// secondpass(right);
afteronflowcontrol:=flowcontrol;
{ default handling except handling }
if assigned(t1) then
begin
{ FPC_CATCHES with 'default handler' flag (=-1) need no longer be called,
it doesn't change any state and its return value is ignored (Sergei)
}
{ the destruction of the exception object must be also }
{ guarded by an exception frame, but it can be omitted }
{ if there's no user code in 'except' block }
if not (has_no_code(t1)) then
begin
{ if there is an outer frame that catches exceptions, remember this for the "except"
part of this try/except }
flowcontrol:=trystate.oldflowcontrol*[fc_inflowcontrol,fc_catching_exceptions];
{ Exception temps? We don't need no stinking exception temps! :) }
fillchar(excepttemps,sizeof(destroytemps),0);
reference_reset(destroytemps.envbuf,0,[]);
reference_reset(destroytemps.jmpbuf,0,[]);
reference_reset(destroytemps.reasonbuf,0,[]);
cexceptionstatehandler.new_exception(current_asmdata.CurrAsmList,destroytemps,tek_except,doobjectdestroyandreraisestate);
{ the flowcontrol from the default except-block must be merged
with the flowcontrol flags potentially set by the
on-statements handled above (secondpass(right)), as they are
at the same program level }
flowcontrol:=
flowcontrol+
afteronflowcontrol;
current_asmdata.CurrAsmList.concat(taicpu.op_none(a_try));
thlcgwasm(hlcg).incblock;
secondpass(t1);
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_doneexception',[],nil).resetiftemp;
current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_catch,current_asmdata.WeakRefAsmSymbol(FPC_EXCEPTION_TAG_SYM,AT_WASM_EXCEPTION_TAG)));
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_raise_nested',[],nil).resetiftemp;
current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_try));
end
else
begin
doobjectdestroyandreraisestate.newflowcontrol:=afteronflowcontrol;
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_doneexception',[],nil).resetiftemp;
end;
end
else
begin
current_asmdata.CurrAsmList.concat(taicpu.op_const(a_rethrow,0));
doobjectdestroyandreraisestate.newflowcontrol:=afteronflowcontrol;
end;
current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end_try));
thlcgwasm(hlcg).decblock;
errorexit:
{ return all used control flow statements }
flowcontrol:=trystate.oldflowcontrol+(doobjectdestroyandreraisestate.newflowcontrol +
trystate.newflowcontrol - [fc_inflowcontrol,fc_catching_exceptions]);
end;
procedure twasmtryexceptnode.pass_generate_code;