|
@@ -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;
|