* load threadvar input/output variable in temp

This commit is contained in:
peter 2002-11-16 17:59:31 +00:00
parent 98ee9c11cc
commit 2facc2b2f7

View File

@ -360,28 +360,41 @@ implementation
{ create a blocknode in which the successive write/read statements will be }
{ put, since they belong together. Also create a dummy statement already to }
{ make inserting of additional statements easier }
newstatement := cstatementnode.create(nil,cnothingnode.create);
newblock := cblocknode.create(newstatement);
newblock:=internalstatements(newstatement);
{ if we don't have a filepara, create one containing the default }
if not assigned(filepara) then
begin
{ create a loadnode for the standard input/output handle }
{ retrieve the symbols for standard input/output handle }
if do_read then
name := 'INPUT'
else
name := 'OUTPUT';
{ if we are compiling the system unit, the systemunit symtable is nil. }
{ however, if we aren't compiling the system unit, another unit could }
{ also have defined the INPUT or OUTPUT symbols. Therefore we need the }
{ separate cases (JM) }
if not searchsysvar(name,srsym,tempowner) then
internalerror(200108141);
{ create the file parameter }
filepara := ccallparanode.create(cloadnode.create(srsym,tempowner),nil);
{ since the input/output variables are threadvars loading them into
a temp once is faster. Create a temp which will hold a pointer to the file }
filetemp := ctempcreatenode.create(voidpointertype,voidpointertype.def.size,true);
addstatement(newstatement,filetemp);
{ make sure the resulttype of the temp (and as such of the }
{ temprefs coming after it) is set (necessary because the }
{ temprefs will be part of the filepara, of which we need }
{ the resulttype later on and temprefs can only be }
{ resulttypepassed if the resulttype of the temp is known) }
resulttypepass(tnode(filetemp));
{ assign the address of the file to the temp }
addstatement(newstatement,
cassignmentnode.create(ctemprefnode.create(filetemp),
caddrnode.create(cloadnode.create(srsym,tempowner))));
{ create a new fileparameter as follows: file_type(temp^) }
{ (so that we pass the value and not the address of the temp }
{ to the read/write routine) }
filepara := ccallparanode.create(ctypeconvnode.create_explicit(
cderefnode.create(ctemprefnode.create(filetemp)),srsym.vartype),nil);
end
else
{ remove filepara from the parameter chain }
@ -398,8 +411,7 @@ implementation
filetemp := ctempcreatenode.create(voidpointertype,voidpointertype.def.size,true);
{ add it to the statements }
newstatement.left := cstatementnode.create(nil,filetemp);
newstatement := tstatementnode(newstatement.left);
addstatement(newstatement,filetemp);
{ make sure the resulttype of the temp (and as such of the }
{ temprefs coming after it) is set (necessary because the }
@ -409,31 +421,27 @@ implementation
resulttypepass(tnode(filetemp));
{ assign the address of the file to the temp }
newstatement.left := cstatementnode.create(nil,
addstatement(newstatement,
cassignmentnode.create(ctemprefnode.create(filetemp),
caddrnode.create(filepara.left)));
newstatement := tstatementnode(newstatement.left);
resulttypepass(newstatement.right);
{ create a new fileparameter as follows: file_type(temp^) }
{ (so that we pass the value and not the address of the temp }
{ to the read/write routine) }
nextpara := ccallparanode.create(ctypeconvnode.create(
nextpara := ccallparanode.create(ctypeconvnode.create_explicit(
cderefnode.create(ctemprefnode.create(filetemp)),filepara.left.resulttype),nil);
{ make sure the type conversion is explicit, otherwise this }
{ typecast won't work }
nextpara.left.toggleflag(nf_explizit);
{ replace the old file para with the new one }
filepara.left := nil;
filepara.free;
filepara := nextpara;
{ the resulttype of the filepara must be set since it's }
{ used below }
filepara.get_paratype;
end;
end;
{ the resulttype of the filepara must be set since it's }
{ used below }
filepara.get_paratype;
{ now, filepara is nowhere referenced anymore, so we can safely dispose it }
{ if something goes wrong or at the end of the procedure }
@ -513,13 +521,11 @@ implementation
{ create temp for result }
temp := ctempcreatenode.create(para.left.resulttype,
para.left.resulttype.def.size,true);
newstatement.left := cstatementnode.create(nil,temp);
addstatement(newstatement,temp);
{ assign result to temp }
newstatement := tstatementnode(newstatement.left);
newstatement.left := cstatementnode.create(nil,
addstatement(newstatement,
cassignmentnode.create(ctemprefnode.create(temp),
para.left));
newstatement := tstatementnode(newstatement.left);
para.left));
{ replace (reused) paranode with temp }
para.left := ctemprefnode.create(temp);
end;
@ -529,17 +535,11 @@ implementation
{ create call statment }
{ since the parameters are in the correct order, we have to insert }
{ the statements always at the end of the current block }
newstatement.left := cstatementnode.create(nil,
ccallnode.createintern(procprefix,para));
newstatement := tstatementnode(newstatement.left);
addstatement(newstatement,ccallnode.createintern(procprefix,para));
{ if we used a temp, free it }
if para.left.nodetype = temprefn then
begin
newstatement.left := cstatementnode.create(nil,
ctempdeletenode.create(temp));
newstatement := tstatementnode(newstatement.left);
end;
addstatement(newstatement,ctempdeletenode.create(temp));
{ process next parameter }
para := nextpara;
@ -746,29 +746,24 @@ implementation
{ create the parameter list: the temp ... }
temp := ctempcreatenode.create(restype^,restype^.def.size,true);
newstatement.left := cstatementnode.create(nil,temp);
newstatement := tstatementnode(newstatement.left);
addstatement(newstatement,temp);
{ ... and the file }
p1 := ccallparanode.create(ctemprefnode.create(temp),
filepara.getcopy);
{ create the call to the helper }
newstatement.left := cstatementnode.create(nil,
addstatement(newstatement,
ccallnode.createintern(name,tcallparanode(p1)));
newstatement := tstatementnode(newstatement.left);
{ assign the result to the original var (this automatically }
{ takes care of range checking) }
newstatement.left := cstatementnode.create(nil,
addstatement(newstatement,
cassignmentnode.create(para.left,
ctemprefnode.create(temp)));
newstatement := tstatementnode(newstatement.left);
ctemprefnode.create(temp)));
{ release the temp location }
newstatement.left := cstatementnode.create(nil,
ctempdeletenode.create(temp));
newstatement := tstatementnode(newstatement.left);
addstatement(newstatement,ctempdeletenode.create(temp));
{ statement of para is used }
para.left := nil;
@ -787,9 +782,8 @@ implementation
{ with it if necessary) }
tcallparanode(para.right).right := lenpara;
{ create the call statement }
newstatement.left := cstatementnode.create(nil,
addstatement(newstatement,
ccallnode.createintern(name,para));
newstatement := tstatementnode(newstatement.left);
end
end
else
@ -819,16 +813,15 @@ implementation
begin
case inlinenumber of
in_read_x:
newstatement.left := ccallnode.createintern('fpc_read_end',filepara);
name:='fpc_read_end';
in_write_x:
newstatement.left := ccallnode.createintern('fpc_write_end',filepara);
name:='fpc_write_end';
in_readln_x:
newstatement.left := ccallnode.createintern('fpc_readln_end',filepara);
name:='fpc_readln_end';
in_writeln_x:
newstatement.left := ccallnode.createintern('fpc_writeln_end',filepara);
name:='fpc_writeln_end';
end;
newstatement.left := cstatementnode.create(nil,newstatement.left);
newstatement := tstatementnode(newstatement.left);
addstatement(newstatement,ccallnode.createintern(name,filepara));
end;
end;
@ -839,11 +832,7 @@ implementation
begin
{ deallocate the temp for the file para if we used one }
if assigned(filetemp) then
begin
newstatement.left := cstatementnode.create(nil,
ctempdeletenode.create(filetemp));
newstatement := tstatementnode(newstatement.left);
end;
addstatement(newstatement,ctempdeletenode.create(filetemp));
{ otherwise return the newly generated block of instructions, }
{ but first free the errornode we generated at the beginning }
result.free;
@ -2412,7 +2401,10 @@ begin
end.
{
$Log$
Revision 1.94 2002-11-15 01:58:52 peter
Revision 1.95 2002-11-16 17:59:31 peter
* load threadvar input/output variable in temp
Revision 1.94 2002/11/15 01:58:52 peter
* merged changes from 1.0.7 up to 04-11
- -V option for generating bug report tracing
- more tracing for option parsing