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