|
@@ -45,6 +45,7 @@ interface
|
|
|
finalizepi: tcgprocinfo;
|
|
|
constructor create(l,r:TNode);override;
|
|
|
constructor create_implicit(l,r:TNode);override;
|
|
|
+ function dogetcopy : tnode;override;
|
|
|
function simplify(forinline: boolean): tnode;override;
|
|
|
procedure pass_generate_code;override;
|
|
|
end;
|
|
@@ -58,7 +59,8 @@ implementation
|
|
|
cgbase,cgobj,cgutils,tgobj,
|
|
|
cpubase,htypechk,
|
|
|
pass_1,pass_2,
|
|
|
- aasmbase,aasmtai,aasmdata,aasmcpu,procinfo,cpupi;
|
|
|
+ aasmbase,aasmtai,aasmdata,aasmcpu,
|
|
|
+ procinfo,cpupi,procdefutil;
|
|
|
|
|
|
var
|
|
|
endexceptlabel: tasmlabel;
|
|
@@ -169,6 +171,7 @@ constructor tx64tryfinallynode.create(l, r: TNode);
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
+
|
|
|
constructor tx64tryfinallynode.create_implicit(l, r: TNode);
|
|
|
begin
|
|
|
inherited create_implicit(l, r);
|
|
@@ -185,6 +188,33 @@ constructor tx64tryfinallynode.create_implicit(l, r: TNode);
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
+
|
|
|
+function tx64tryfinallynode.dogetcopy: tnode;
|
|
|
+ var
|
|
|
+ n: tx64tryfinallynode;
|
|
|
+ begin
|
|
|
+ n:=tx64tryfinallynode(inherited dogetcopy);
|
|
|
+ if target_info.system=system_x86_64_win64 then
|
|
|
+ begin
|
|
|
+ n.finalizepi:=tcgprocinfo(cprocinfo.create(finalizepi.parent));
|
|
|
+ n.finalizepi.force_nested;
|
|
|
+ n.finalizepi.procdef:=create_outline_procdef('$fin$',current_procinfo.procdef.struct,potype_exceptfilter,voidtype);
|
|
|
+ n.finalizepi.entrypos:=finalizepi.entrypos;
|
|
|
+ n.finalizepi.entryswitches:=finalizepi.entryswitches;
|
|
|
+ n.finalizepi.exitpos:=finalizepi.exitpos;
|
|
|
+ n.finalizepi.exitswitches:=finalizepi.exitswitches;
|
|
|
+ n.finalizepi.flags:=finalizepi.flags;
|
|
|
+ { node already transformed? }
|
|
|
+ if assigned(finalizepi.code) then
|
|
|
+ begin
|
|
|
+ n.finalizepi.code:=finalizepi.code.getcopy;
|
|
|
+ n.right:=ccallnode.create(nil,tprocsym(n.finalizepi.procdef.procsym),nil,nil,[],nil);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ result:=n;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
function tx64tryfinallynode.simplify(forinline: boolean): tnode;
|
|
|
begin
|
|
|
result:=inherited simplify(forinline);
|
|
@@ -192,22 +222,27 @@ function tx64tryfinallynode.simplify(forinline: boolean): tnode;
|
|
|
exit;
|
|
|
if (result=nil) then
|
|
|
begin
|
|
|
- finalizepi.code:=right;
|
|
|
- foreachnodestatic(right,@copy_parasize,finalizepi);
|
|
|
- right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[],nil);
|
|
|
- firstpass(right);
|
|
|
- { For implicit frames, no actual code is available at this time,
|
|
|
- it is added later in assembler form. So store the nested procinfo
|
|
|
- for later use. }
|
|
|
- if implicitframe then
|
|
|
+ { actually, this is not really the right place to do a node transformation like this }
|
|
|
+ if not(assigned(finalizepi.code)) then
|
|
|
begin
|
|
|
- current_procinfo.finalize_procinfo:=finalizepi;
|
|
|
+ finalizepi.code:=right;
|
|
|
+ foreachnodestatic(right,@copy_parasize,finalizepi);
|
|
|
+ right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[],nil);
|
|
|
+ firstpass(right);
|
|
|
+ { For implicit frames, no actual code is available at this time,
|
|
|
+ it is added later in assembler form. So store the nested procinfo
|
|
|
+ for later use. }
|
|
|
+ if implicitframe then
|
|
|
+ begin
|
|
|
+ current_procinfo.finalize_procinfo:=finalizepi;
|
|
|
+ end;
|
|
|
{ don't leave dangling pointer }
|
|
|
tcgprocinfo(current_procinfo).final_asmnode:=nil;
|
|
|
end;
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
+
|
|
|
procedure emit_nop;
|
|
|
var
|
|
|
dummy: TAsmLabel;
|
|
@@ -219,6 +254,7 @@ procedure emit_nop;
|
|
|
current_asmdata.CurrAsmList.concat(Taicpu.op_none(A_NOP,S_NO));
|
|
|
end;
|
|
|
|
|
|
+
|
|
|
procedure tx64tryfinallynode.pass_generate_code;
|
|
|
var
|
|
|
trylabel,
|