mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 19:29:18 +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,
|
symconst,symdef,symsym,aasmtai,aasmdata,aasmcpu,defutil,defcmp,
|
||||||
procinfo,cgbase,cgexcept,pass_1,pass_2,parabase,compinnr,
|
procinfo,cgbase,cgexcept,pass_1,pass_2,parabase,compinnr,
|
||||||
cpubase,cpuinfo,
|
cpubase,cpuinfo,
|
||||||
nbas,nld,ncon,ncnv,ncal,ninl,nmem,nadd,
|
nbas,nld,ncon,ncnv,ncal,ninl,nmem,nadd,nutils,
|
||||||
tgobj,paramgr,
|
tgobj,paramgr,
|
||||||
cgutils,hlcgobj,hlcgcpu;
|
cgutils,hlcgobj,hlcgcpu;
|
||||||
|
|
||||||
@ -365,9 +365,109 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure twasmtryexceptnode.pass_generate_code_native_exceptions;
|
procedure twasmtryexceptnode.pass_generate_code_native_exceptions;
|
||||||
|
var
|
||||||
|
trystate,doobjectdestroyandreraisestate: tcgexceptionstatehandler.texceptionstate;
|
||||||
|
destroytemps,
|
||||||
|
excepttemps: tcgexceptionstatehandler.texceptiontemps;
|
||||||
|
afteronflowcontrol: tflowcontrol;
|
||||||
|
label
|
||||||
|
errorexit;
|
||||||
begin
|
begin
|
||||||
location_reset(location,LOC_VOID,OS_NO);
|
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);
|
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;
|
end;
|
||||||
|
|
||||||
procedure twasmtryexceptnode.pass_generate_code;
|
procedure twasmtryexceptnode.pass_generate_code;
|
||||||
|
Loading…
Reference in New Issue
Block a user