mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-19 23:19:24 +02:00
+ initial implementation of try..except..end in wasm native exceptions mode.
The 'on' statements are not implemented yet.
This commit is contained in:
parent
93b3315691
commit
f2abce7ea5
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user