Przeglądaj źródła

* load threadvar input/output variable in temp

peter 23 lat temu
rodzic
commit
2facc2b2f7
1 zmienionych plików z 52 dodań i 60 usunięć
  1. 52 60
      compiler/ninl.pas

+ 52 - 60
compiler/ninl.pas

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