+ 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:
florian 2010-01-10 13:19:16 +00:00
parent 49f01e7b64
commit 7707e6a030
2 changed files with 48 additions and 3 deletions

View File

@ -94,7 +94,8 @@ interface
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;
const
@ -116,6 +117,7 @@ type
withnode : tnode;
location : tlocation;
flags : ttempinfoflags;
tempinitcode : tnode;
end;
{ a node which will create a (non)persistent temp of a given type with a given }
@ -123,6 +125,7 @@ type
ttempcreatenode = class(tnode)
size: aint;
tempinfo: ptempinfo;
ftemplvalue : tnode;
{ * persistent temps are used in manually written code where the temp }
{ be usable among different statements and where you can manually say }
{ when the temp has to be freed (using a ttempdeletenode) }
@ -132,6 +135,7 @@ type
{ to it and *not* generate a ttempdeletenode }
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_value(_typedef:tdef; _size: aint; _temptype: ttemptype;allowreg:boolean; templvalue: tnode);
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure buildderefimpl;override;
@ -732,6 +736,7 @@ implementation
include(tempinfo^.flags,ti_may_be_in_reg);
end;
constructor ttempcreatenode.create_withnode(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean; withnode: tnode);
begin
self.create(_typedef,_size,_temptype,allowreg);
@ -739,6 +744,16 @@ implementation
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;
var
n: ttempcreatenode;
@ -757,6 +772,11 @@ implementation
else
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
reset by a tempdeletenode }
if assigned(tempinfo^.hookoncopy) then
@ -784,6 +804,7 @@ implementation
tempinfo^.temptype := ttemptype(ppufile.getbyte);
tempinfo^.owner:=self;
tempinfo^.withnode:=ppuloadnode(ppufile);
ftemplvalue:=ppuloadnode(ppufile);
end;
@ -795,6 +816,7 @@ implementation
ppufile.putderef(tempinfo^.typedefderef);
ppufile.putbyte(byte(tempinfo^.temptype));
ppuwritenode(ppufile,tempinfo^.withnode);
ppuwritenode(ppufile,ftemplvalue);
end;
@ -804,6 +826,8 @@ implementation
tempinfo^.typedefderef.build(tempinfo^.typedef);
if assigned(tempinfo^.withnode) then
tempinfo^.withnode.buildderefimpl;
if assigned(ftemplvalue) then
ftemplvalue.buildderefimpl;
end;
@ -813,6 +837,11 @@ implementation
tempinfo^.typedef:=tdef(tempinfo^.typedefderef.resolve);
if assigned(tempinfo^.withnode) then
tempinfo^.withnode.derefimpl;
if assigned(ftemplvalue) then
begin
ftemplvalue.derefimpl;
tempinfo^.tempinitcode:=cassignmentnode.create(ctemprefnode.create(self),ftemplvalue);
end;
end;
@ -824,6 +853,8 @@ implementation
include(current_procinfo.flags,pi_needs_implicit_finally);
if assigned(tempinfo^.withnode) then
firstpass(tempinfo^.withnode);
if assigned(tempinfo^.tempinitcode) then
firstpass(tempinfo^.tempinitcode);
end;
@ -834,6 +865,8 @@ implementation
resultdef := voidtype;
if assigned(tempinfo^.withnode) then
typecheckpass(tempinfo^.withnode);
if assigned(tempinfo^.tempinitcode) then
typecheckpass(tempinfo^.tempinitcode);
end;
@ -843,8 +876,9 @@ implementation
inherited docompare(p) and
(ttempcreatenode(p).size = size) 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
equal_defs(ttempcreatenode(p).tempinfo^.typedef,tempinfo^.typedef);
(ttempcreatenode(p).tempinfo^.tempinitcode.isequal(tempinfo^.tempinitcode));
end;
@ -959,6 +993,7 @@ implementation
result := nil;
end;
function ttemprefnode.pass_typecheck: tnode;
begin
{ check if the temp is already resultdef passed }
@ -968,6 +1003,7 @@ implementation
resultdef := tempinfo^.typedef;
end;
function ttemprefnode.docompare(p: tnode): boolean;
begin
result :=
@ -976,7 +1012,8 @@ implementation
(ttemprefnode(p).offset = offset);
end;
procedure Ttemprefnode.mark_write;
procedure ttemprefnode.mark_write;
begin
include(flags,nf_write);

View File

@ -449,6 +449,8 @@ interface
tg.GetTemp(current_asmdata.CurrAsmList,size,tempinfo^.typedef.alignment,tempinfo^.temptype,tempinfo^.location.reference);
end;
include(tempinfo^.flags,ti_valid);
if assigned(tempinfo^.tempinitcode) then
include(tempinfo^.flags,ti_executeinitialisation);
end;
@ -458,6 +460,12 @@ interface
procedure tcgtemprefnode.pass_generate_code;
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 }
if not(ti_valid in tempinfo^.flags) then
internalerror(200108231);