mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 02:19:33 +02:00
+ tempcreate nodes can now take an init. value, this allows to initilialize temp. ref nodes on the fly
git-svn-id: trunk@14595 -
This commit is contained in:
parent
49f01e7b64
commit
7707e6a030
@ -94,7 +94,8 @@ interface
|
|||||||
|
|
||||||
ttempcreatenode = class;
|
ttempcreatenode = class;
|
||||||
|
|
||||||
ttempinfoflag = (ti_may_be_in_reg,ti_valid,ti_nextref_set_hookoncopy_nil,ti_addr_taken);
|
ttempinfoflag = (ti_may_be_in_reg,ti_valid,ti_nextref_set_hookoncopy_nil,
|
||||||
|
ti_addr_taken,ti_executeinitialisation);
|
||||||
ttempinfoflags = set of ttempinfoflag;
|
ttempinfoflags = set of ttempinfoflag;
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -116,6 +117,7 @@ type
|
|||||||
withnode : tnode;
|
withnode : tnode;
|
||||||
location : tlocation;
|
location : tlocation;
|
||||||
flags : ttempinfoflags;
|
flags : ttempinfoflags;
|
||||||
|
tempinitcode : tnode;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ a node which will create a (non)persistent temp of a given type with a given }
|
{ a node which will create a (non)persistent temp of a given type with a given }
|
||||||
@ -123,6 +125,7 @@ type
|
|||||||
ttempcreatenode = class(tnode)
|
ttempcreatenode = class(tnode)
|
||||||
size: aint;
|
size: aint;
|
||||||
tempinfo: ptempinfo;
|
tempinfo: ptempinfo;
|
||||||
|
ftemplvalue : tnode;
|
||||||
{ * persistent temps are used in manually written code where the temp }
|
{ * persistent temps are used in manually written code where the temp }
|
||||||
{ be usable among different statements and where you can manually say }
|
{ be usable among different statements and where you can manually say }
|
||||||
{ when the temp has to be freed (using a ttempdeletenode) }
|
{ when the temp has to be freed (using a ttempdeletenode) }
|
||||||
@ -132,6 +135,7 @@ type
|
|||||||
{ to it and *not* generate a ttempdeletenode }
|
{ to it and *not* generate a ttempdeletenode }
|
||||||
constructor create(_typedef: tdef; _size: aint; _temptype: ttemptype;allowreg:boolean); virtual;
|
constructor create(_typedef: tdef; _size: aint; _temptype: ttemptype;allowreg:boolean); virtual;
|
||||||
constructor create_withnode(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean; withnode: tnode); virtual;
|
constructor create_withnode(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean; withnode: tnode); virtual;
|
||||||
|
constructor create_value(_typedef:tdef; _size: aint; _temptype: ttemptype;allowreg:boolean; templvalue: tnode);
|
||||||
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
|
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
|
||||||
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
||||||
procedure buildderefimpl;override;
|
procedure buildderefimpl;override;
|
||||||
@ -732,6 +736,7 @@ implementation
|
|||||||
include(tempinfo^.flags,ti_may_be_in_reg);
|
include(tempinfo^.flags,ti_may_be_in_reg);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
constructor ttempcreatenode.create_withnode(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean; withnode: tnode);
|
constructor ttempcreatenode.create_withnode(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean; withnode: tnode);
|
||||||
begin
|
begin
|
||||||
self.create(_typedef,_size,_temptype,allowreg);
|
self.create(_typedef,_size,_temptype,allowreg);
|
||||||
@ -739,6 +744,16 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
constructor ttempcreatenode.create_value(_typedef:tdef; _size: aint; _temptype: ttemptype;allowreg:boolean; templvalue: tnode);
|
||||||
|
begin
|
||||||
|
self.create(_typedef,_size,_temptype,allowreg);
|
||||||
|
// store in ppuwrite
|
||||||
|
ftemplvalue:=templvalue;
|
||||||
|
// create from stored ftemplvalue in ppuload
|
||||||
|
tempinfo^.tempinitcode:=cassignmentnode.create(ctemprefnode.create(self),ftemplvalue);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttempcreatenode.dogetcopy: tnode;
|
function ttempcreatenode.dogetcopy: tnode;
|
||||||
var
|
var
|
||||||
n: ttempcreatenode;
|
n: ttempcreatenode;
|
||||||
@ -757,6 +772,11 @@ implementation
|
|||||||
else
|
else
|
||||||
n.tempinfo^.withnode := nil;
|
n.tempinfo^.withnode := nil;
|
||||||
|
|
||||||
|
if assigned(tempinfo^.tempinitcode) then
|
||||||
|
n.tempinfo^.tempinitcode := tempinfo^.tempinitcode.getcopy
|
||||||
|
else
|
||||||
|
n.tempinfo^.tempinitcode := nil;
|
||||||
|
|
||||||
{ when the tempinfo has already a hookoncopy then it is not
|
{ when the tempinfo has already a hookoncopy then it is not
|
||||||
reset by a tempdeletenode }
|
reset by a tempdeletenode }
|
||||||
if assigned(tempinfo^.hookoncopy) then
|
if assigned(tempinfo^.hookoncopy) then
|
||||||
@ -784,6 +804,7 @@ implementation
|
|||||||
tempinfo^.temptype := ttemptype(ppufile.getbyte);
|
tempinfo^.temptype := ttemptype(ppufile.getbyte);
|
||||||
tempinfo^.owner:=self;
|
tempinfo^.owner:=self;
|
||||||
tempinfo^.withnode:=ppuloadnode(ppufile);
|
tempinfo^.withnode:=ppuloadnode(ppufile);
|
||||||
|
ftemplvalue:=ppuloadnode(ppufile);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -795,6 +816,7 @@ implementation
|
|||||||
ppufile.putderef(tempinfo^.typedefderef);
|
ppufile.putderef(tempinfo^.typedefderef);
|
||||||
ppufile.putbyte(byte(tempinfo^.temptype));
|
ppufile.putbyte(byte(tempinfo^.temptype));
|
||||||
ppuwritenode(ppufile,tempinfo^.withnode);
|
ppuwritenode(ppufile,tempinfo^.withnode);
|
||||||
|
ppuwritenode(ppufile,ftemplvalue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -804,6 +826,8 @@ implementation
|
|||||||
tempinfo^.typedefderef.build(tempinfo^.typedef);
|
tempinfo^.typedefderef.build(tempinfo^.typedef);
|
||||||
if assigned(tempinfo^.withnode) then
|
if assigned(tempinfo^.withnode) then
|
||||||
tempinfo^.withnode.buildderefimpl;
|
tempinfo^.withnode.buildderefimpl;
|
||||||
|
if assigned(ftemplvalue) then
|
||||||
|
ftemplvalue.buildderefimpl;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -813,6 +837,11 @@ implementation
|
|||||||
tempinfo^.typedef:=tdef(tempinfo^.typedefderef.resolve);
|
tempinfo^.typedef:=tdef(tempinfo^.typedefderef.resolve);
|
||||||
if assigned(tempinfo^.withnode) then
|
if assigned(tempinfo^.withnode) then
|
||||||
tempinfo^.withnode.derefimpl;
|
tempinfo^.withnode.derefimpl;
|
||||||
|
if assigned(ftemplvalue) then
|
||||||
|
begin
|
||||||
|
ftemplvalue.derefimpl;
|
||||||
|
tempinfo^.tempinitcode:=cassignmentnode.create(ctemprefnode.create(self),ftemplvalue);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -824,6 +853,8 @@ implementation
|
|||||||
include(current_procinfo.flags,pi_needs_implicit_finally);
|
include(current_procinfo.flags,pi_needs_implicit_finally);
|
||||||
if assigned(tempinfo^.withnode) then
|
if assigned(tempinfo^.withnode) then
|
||||||
firstpass(tempinfo^.withnode);
|
firstpass(tempinfo^.withnode);
|
||||||
|
if assigned(tempinfo^.tempinitcode) then
|
||||||
|
firstpass(tempinfo^.tempinitcode);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -834,6 +865,8 @@ implementation
|
|||||||
resultdef := voidtype;
|
resultdef := voidtype;
|
||||||
if assigned(tempinfo^.withnode) then
|
if assigned(tempinfo^.withnode) then
|
||||||
typecheckpass(tempinfo^.withnode);
|
typecheckpass(tempinfo^.withnode);
|
||||||
|
if assigned(tempinfo^.tempinitcode) then
|
||||||
|
typecheckpass(tempinfo^.tempinitcode);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -843,8 +876,9 @@ implementation
|
|||||||
inherited docompare(p) and
|
inherited docompare(p) and
|
||||||
(ttempcreatenode(p).size = size) and
|
(ttempcreatenode(p).size = size) and
|
||||||
(ttempcreatenode(p).tempinfo^.flags*tempinfostoreflags=tempinfo^.flags*tempinfostoreflags) and
|
(ttempcreatenode(p).tempinfo^.flags*tempinfostoreflags=tempinfo^.flags*tempinfostoreflags) and
|
||||||
|
equal_defs(ttempcreatenode(p).tempinfo^.typedef,tempinfo^.typedef) and
|
||||||
(ttempcreatenode(p).tempinfo^.withnode.isequal(tempinfo^.withnode)) and
|
(ttempcreatenode(p).tempinfo^.withnode.isequal(tempinfo^.withnode)) and
|
||||||
equal_defs(ttempcreatenode(p).tempinfo^.typedef,tempinfo^.typedef);
|
(ttempcreatenode(p).tempinfo^.tempinitcode.isequal(tempinfo^.tempinitcode));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -959,6 +993,7 @@ implementation
|
|||||||
result := nil;
|
result := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttemprefnode.pass_typecheck: tnode;
|
function ttemprefnode.pass_typecheck: tnode;
|
||||||
begin
|
begin
|
||||||
{ check if the temp is already resultdef passed }
|
{ check if the temp is already resultdef passed }
|
||||||
@ -968,6 +1003,7 @@ implementation
|
|||||||
resultdef := tempinfo^.typedef;
|
resultdef := tempinfo^.typedef;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttemprefnode.docompare(p: tnode): boolean;
|
function ttemprefnode.docompare(p: tnode): boolean;
|
||||||
begin
|
begin
|
||||||
result :=
|
result :=
|
||||||
@ -976,7 +1012,8 @@ implementation
|
|||||||
(ttemprefnode(p).offset = offset);
|
(ttemprefnode(p).offset = offset);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure Ttemprefnode.mark_write;
|
|
||||||
|
procedure ttemprefnode.mark_write;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
include(flags,nf_write);
|
include(flags,nf_write);
|
||||||
|
@ -449,6 +449,8 @@ interface
|
|||||||
tg.GetTemp(current_asmdata.CurrAsmList,size,tempinfo^.typedef.alignment,tempinfo^.temptype,tempinfo^.location.reference);
|
tg.GetTemp(current_asmdata.CurrAsmList,size,tempinfo^.typedef.alignment,tempinfo^.temptype,tempinfo^.location.reference);
|
||||||
end;
|
end;
|
||||||
include(tempinfo^.flags,ti_valid);
|
include(tempinfo^.flags,ti_valid);
|
||||||
|
if assigned(tempinfo^.tempinitcode) then
|
||||||
|
include(tempinfo^.flags,ti_executeinitialisation);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -458,6 +460,12 @@ interface
|
|||||||
|
|
||||||
procedure tcgtemprefnode.pass_generate_code;
|
procedure tcgtemprefnode.pass_generate_code;
|
||||||
begin
|
begin
|
||||||
|
if ti_executeinitialisation in tempinfo^.flags then
|
||||||
|
begin
|
||||||
|
{ avoid recursion }
|
||||||
|
exclude(tempinfo^.flags, ti_executeinitialisation);
|
||||||
|
secondpass(tempinfo^.tempinitcode);
|
||||||
|
end;
|
||||||
{ check if the temp is valid }
|
{ check if the temp is valid }
|
||||||
if not(ti_valid in tempinfo^.flags) then
|
if not(ti_valid in tempinfo^.flags) then
|
||||||
internalerror(200108231);
|
internalerror(200108231);
|
||||||
|
Loading…
Reference in New Issue
Block a user