Forráskód Böngészése

+ compilerproc implementation of most string-related type conversions
- removed all code from the compiler which has been replaced by
compilerproc implementations (using {$ifdef hascompilerproc} is not
necessary in the compiler)

Jonas Maebe 24 éve
szülő
commit
fc92c3b336
10 módosított fájl, 432 hozzáadás és 1803 törlés
  1. 14 367
      compiler/i386/n386cnv.pas
  2. 7 838
      compiler/i386/n386inl.pas
  3. 11 6
      compiler/ncal.pas
  4. 78 28
      compiler/ncnv.pas
  5. 7 411
      compiler/ninl.pas
  6. 52 11
      rtl/i386/i386.inc
  7. 78 45
      rtl/inc/astrings.inc
  8. 24 17
      rtl/inc/compproc.inc
  9. 39 5
      rtl/inc/generic.inc
  10. 122 75
      rtl/inc/wstrings.inc

+ 14 - 367
compiler/i386/n386cnv.pas

@@ -32,12 +32,12 @@ interface
     type
        ti386typeconvnode = class(ttypeconvnode)
           procedure second_int_to_int;virtual;
-          procedure second_string_to_string;virtual;
+         { procedure second_string_to_string;virtual; }
           procedure second_cstring_to_pchar;virtual;
           procedure second_string_to_chararray;virtual;
           procedure second_array_to_pointer;virtual;
           procedure second_pointer_to_array;virtual;
-          procedure second_chararray_to_string;virtual;
+         { procedure second_chararray_to_string;virtual; }
           procedure second_char_to_string;virtual;
           procedure second_int_to_real;virtual;
           procedure second_real_to_real;virtual;
@@ -47,7 +47,7 @@ interface
           procedure second_int_to_bool;virtual;
           procedure second_load_smallset;virtual;
           procedure second_ansistring_to_pchar;virtual;
-          procedure second_pchar_to_string;virtual;
+         { procedure second_pchar_to_string;virtual; }
           procedure second_class_to_intf;virtual;
           procedure second_char_to_char;virtual;
           procedure second_nothing;virtual;
@@ -200,154 +200,6 @@ implementation
           end;
       end;
 
-    procedure ti386typeconvnode.second_string_to_string;
-
-      var
-         pushed : tpushed;
-         regs_to_push: byte;
-
-      begin
-         { does anybody know a better solution than this big case statement ? }
-         { ok, a proc table would do the job                              }
-         case tstringdef(resulttype.def).string_typ of
-
-            st_shortstring:
-              case tstringdef(left.resulttype.def).string_typ of
-                 st_shortstring:
-                   begin
-                      gettempofsizereference(resulttype.def.size,location.reference);
-                      copyshortstring(location.reference,left.location.reference,
-                                      tstringdef(resulttype.def).len,false,true);
-                      ungetiftemp(left.location.reference);
-                   end;
-                 st_ansistring:
-                   begin
-                      gettempofsizereference(resulttype.def.size,location.reference);
-                      loadansi2short(left,self);
-                   end;
-                 st_widestring:
-                   begin
-                      gettempofsizereference(resulttype.def.size,location.reference);
-                      loadwide2short(left,self);
-                   end;
-                 st_longstring:
-                   begin
-                      {!!!!!!!}
-                      internalerror(8888);
-                   end;
-              end;
-
-            st_ansistring:
-              case tstringdef(left.resulttype.def).string_typ of
-                 st_shortstring:
-                   begin
-                      clear_location(location);
-                      location.loc:=LOC_REFERENCE;
-                      gettempansistringreference(location.reference);
-                      decrstringref(cansistringtype.def,location.reference);
-                      { We don't need the source regs anymore (JM) }
-                      regs_to_push := $ff;
-                      remove_non_regvars_from_loc(left.location,regs_to_push);
-                      pushusedregisters(pushed,regs_to_push);
-                      release_loc(left.location);
-                      emit_push_lea_loc(left.location,true);
-                      emit_push_lea_loc(location,false);
-                      saveregvars(regs_to_push);
-                      emitcall('FPC_SHORTSTR_TO_ANSISTR');
-                      maybe_loadself;
-                      popusedregisters(pushed);
-                   end;
-                 st_widestring:
-                   begin
-                      clear_location(location);
-                      location.loc:=LOC_REFERENCE;
-                      gettempansistringreference(location.reference);
-                      decrstringref(cansistringtype.def,location.reference);
-                      { We don't need the source regs anymore (JM) }
-                      regs_to_push := $ff;
-                      remove_non_regvars_from_loc(left.location,regs_to_push);
-                      pushusedregisters(pushed,regs_to_push);
-                      release_loc(left.location);
-                      emit_push_loc(left.location);
-                      emit_push_lea_loc(location,false);
-                      saveregvars(regs_to_push);
-                      emitcall('FPC_WIDESTR_TO_ANSISTR');
-                      maybe_loadself;
-                      popusedregisters(pushed);
-                   end;
-                 st_longstring:
-                   begin
-                      {!!!!!!!}
-                      internalerror(8888);
-                   end;
-              end;
-
-            st_widestring:
-              case tstringdef(left.resulttype.def).string_typ of
-                 st_shortstring:
-                   begin
-                      clear_location(location);
-                      location.loc:=LOC_REFERENCE;
-                      gettempwidestringreference(location.reference);
-                      decrstringref(cwidestringtype.def,location.reference);
-                      { We don't need the source regs anymore (JM) }
-                      regs_to_push := $ff;
-                      remove_non_regvars_from_loc(left.location,regs_to_push);
-                      pushusedregisters(pushed,regs_to_push);
-                      release_loc(left.location);
-                      emit_push_lea_loc(left.location,true);
-                      emit_push_lea_loc(location,false);
-                      saveregvars(regs_to_push);
-                      emitcall('FPC_SHORTSTR_TO_WIDESTR');
-                      maybe_loadself;
-                      popusedregisters(pushed);
-                   end;
-                 st_ansistring:
-                   begin
-                      clear_location(location);
-                      location.loc:=LOC_REFERENCE;
-                      gettempwidestringreference(location.reference);
-                      decrstringref(cwidestringtype.def,location.reference);
-                      { We don't need the source regs anymore (JM) }
-                      regs_to_push := $ff;
-                      remove_non_regvars_from_loc(left.location,regs_to_push);
-                      pushusedregisters(pushed,regs_to_push);
-                      release_loc(left.location);
-                      emit_push_loc(left.location);
-                      emit_push_lea_loc(location,false);
-                      saveregvars(regs_to_push);
-                      emitcall('FPC_ANSISTR_TO_WIDESTR');
-                      maybe_loadself;
-                      popusedregisters(pushed);
-                   end;
-                 st_longstring:
-                   begin
-                      {!!!!!!!}
-                      internalerror(8888);
-                   end;
-              end;
-
-            st_longstring:
-              case tstringdef(left.resulttype.def).string_typ of
-                 st_shortstring:
-                   begin
-                      {!!!!!!!}
-                      internalerror(8888);
-                   end;
-                 st_ansistring:
-                   begin
-                      {!!!!!!!}
-                      internalerror(8888);
-                   end;
-                 st_widestring:
-                   begin
-                      {!!!!!!!}
-                      internalerror(8888);
-                   end;
-              end;
-         end;
-      end;
-
 
     procedure ti386typeconvnode.second_cstring_to_pchar;
       var
@@ -532,92 +384,7 @@ implementation
       end;
 
 
-    { generates the code for the type conversion from an array of char }
-    { to a string                                                       }
-    procedure ti386typeconvnode.second_chararray_to_string;
-      var
-         pushed : tpushed;
-         regstopush: byte;
-         l : longint;
-      begin
-         { calc the length of the array }
-         l:=tarraydef(left.resulttype.def).highrange-tarraydef(left.resulttype.def).lowrange+1;
-         { this is a type conversion which copies the data, so we can't }
-         { return a reference                                        }
-         clear_location(location);
-         location.loc:=LOC_MEM;
-         case tstringdef(resulttype.def).string_typ of
-           st_shortstring :
-             begin
-               if l>255 then
-                begin
-                  CGMessage(type_e_mismatch);
-                  l:=255;
-                end;
-               gettempofsizereference(resulttype.def.size,location.reference);
-               { we've also to release the registers ... }
-               { Yes, but before pushusedregisters since that one resets unused! }
-               { This caused web bug 1073 (JM)                                   }
-               regstopush := $ff;
-               remove_non_regvars_from_loc(left.location,regstopush);
-               pushusedregisters(pushed,regstopush);
-               if l>=resulttype.def.size then
-                 push_int(resulttype.def.size-1)
-               else
-                 push_int(l);
-               { ... here only the temp. location is released }
-               emit_push_lea_loc(left.location,true);
-               del_reference(left.location.reference);
-               emitpushreferenceaddr(location.reference);
-               saveregvars(regstopush);
-               emitcall('FPC_CHARARRAY_TO_SHORTSTR');
-               maybe_loadself;
-               popusedregisters(pushed);
-             end;
-           st_ansistring :
-             begin
-               gettempansistringreference(location.reference);
-               decrstringref(cansistringtype.def,location.reference);
-               regstopush := $ff;
-               remove_non_regvars_from_loc(left.location,regstopush);
-               pushusedregisters(pushed,regstopush);
-               push_int(l);
-               emitpushreferenceaddr(left.location.reference);
-               release_loc(left.location);
-               emitpushreferenceaddr(location.reference);
-               saveregvars(regstopush);
-               emitcall('FPC_CHARARRAY_TO_ANSISTR');
-               popusedregisters(pushed);
-               maybe_loadself;
-             end;
-           st_widestring :
-             begin
-               gettempwidestringreference(location.reference);
-               decrstringref(cwidestringtype.def,location.reference);
-               regstopush := $ff;
-               remove_non_regvars_from_loc(left.location,regstopush);
-               pushusedregisters(pushed,regstopush);
-               push_int(l);
-               emitpushreferenceaddr(left.location.reference);
-               release_loc(left.location);
-               emitpushreferenceaddr(location.reference);
-               saveregvars(regstopush);
-               emitcall('FPC_CHARARRAY_TO_WIDESTR');
-               popusedregisters(pushed);
-               maybe_loadself;
-             end;
-           st_longstring:
-             begin
-               {!!!!!!!}
-               internalerror(8888);
-             end;
-        end;
-      end;
-
-
     procedure ti386typeconvnode.second_char_to_string;
-      var
-        pushed : tpushed;
 
       begin
          clear_location(location);
@@ -628,32 +395,7 @@ implementation
                gettempofsizereference(256,location.reference);
                loadshortstring(left,self);
              end;
-           st_ansistring :
-             begin
-               gettempansistringreference(location.reference);
-               decrstringref(cansistringtype.def,location.reference);
-               release_loc(left.location);
-               pushusedregisters(pushed,$ff);
-               emit_pushw_loc(left.location);
-               emitpushreferenceaddr(location.reference);
-               saveregvars($ff);
-               emitcall('FPC_CHAR_TO_ANSISTR');
-               popusedregisters(pushed);
-               maybe_loadself;
-             end;
-           st_widestring :
-             begin
-               gettempwidestringreference(location.reference);
-               decrstringref(cwidestringtype.def,location.reference);
-               release_loc(left.location);
-               pushusedregisters(pushed,$ff);
-               emit_pushw_loc(left.location);
-               emitpushreferenceaddr(location.reference);
-               saveregvars($ff);
-               emitcall('FPC_CHAR_TO_WIDESTR');
-               popusedregisters(pushed);
-               maybe_loadself;
-             end;
+           { the rest is removed in the resulttype pass and coverted to compilerprocs }
            else
             internalerror(4179);
         end;
@@ -1049,107 +791,6 @@ implementation
       end;
 
 
-    procedure ti386typeconvnode.second_pchar_to_string;
-      var
-        pushed : tpushed;
-        regs_to_push: byte;
-      begin
-         case tstringdef(resulttype.def).string_typ of
-           st_shortstring:
-             begin
-                location.loc:=LOC_REFERENCE;
-                gettempofsizereference(resulttype.def.size,location.reference);
-                pushusedregisters(pushed,$ff);
-                case left.location.loc of
-                   LOC_REGISTER,LOC_CREGISTER:
-                     begin
-                        emit_reg(A_PUSH,S_L,left.location.register);
-                        ungetregister32(left.location.register);
-                     end;
-                   LOC_REFERENCE,LOC_MEM:
-                     begin
-                       { Now release the registers (see cgai386.pas:     }
-                       { loadansistring for more info on the order) (JM) }
-                        del_reference(left.location.reference);
-                        emit_push_mem(left.location.reference);
-                     end;
-                end;
-                emitpushreferenceaddr(location.reference);
-                saveregvars($ff);
-                emitcall('FPC_PCHAR_TO_SHORTSTR');
-                maybe_loadself;
-                popusedregisters(pushed);
-             end;
-           st_ansistring:
-             begin
-                location.loc:=LOC_REFERENCE;
-                gettempansistringreference(location.reference);
-                decrstringref(cansistringtype.def,location.reference);
-                { Find out which regs have to be pushed (JM) }
-                regs_to_push := $ff;
-                remove_non_regvars_from_loc(left.location,regs_to_push);
-                pushusedregisters(pushed,regs_to_push);
-                case left.location.loc of
-                  LOC_REFERENCE,LOC_MEM:
-                    begin
-                      { Now release the registers (see cgai386.pas:     }
-                      { loadansistring for more info on the order) (JM) }
-                      del_reference(left.location.reference);
-                      emit_push_mem(left.location.reference);
-                    end;
-                  LOC_REGISTER,LOC_CREGISTER:
-                    begin
-                       { Now release the registers (see cgai386.pas:     }
-                       { loadansistring for more info on the order) (JM) }
-                      emit_reg(A_PUSH,S_L,left.location.register);
-                      ungetregister32(left.location.register);
-                   end;
-                end;
-                emitpushreferenceaddr(location.reference);
-                saveregvars(regs_to_push);
-                emitcall('FPC_PCHAR_TO_ANSISTR');
-                maybe_loadself;
-                popusedregisters(pushed);
-             end;
-           st_widestring:
-             begin
-                location.loc:=LOC_REFERENCE;
-                gettempwidestringreference(location.reference);
-                decrstringref(cwidestringtype.def,location.reference);
-                { Find out which regs have to be pushed (JM) }
-                regs_to_push := $ff;
-                remove_non_regvars_from_loc(left.location,regs_to_push);
-                pushusedregisters(pushed,regs_to_push);
-                case left.location.loc of
-                  LOC_REFERENCE,LOC_MEM:
-                    begin
-                      { Now release the registers (see cgai386.pas:     }
-                      { loadansistring for more info on the order) (JM) }
-                      del_reference(left.location.reference);
-                      emit_push_mem(left.location.reference);
-                    end;
-                  LOC_REGISTER,LOC_CREGISTER:
-                    begin
-                       { Now release the registers (see cgai386.pas:     }
-                       { loadansistring for more info on the order) (JM) }
-                      emit_reg(A_PUSH,S_L,left.location.register);
-                      ungetregister32(left.location.register);
-                   end;
-                end;
-                emitpushreferenceaddr(location.reference);
-                saveregvars(regs_to_push);
-                emitcall('FPC_PCHAR_TO_WIDESTR');
-                maybe_loadself;
-                popusedregisters(pushed);
-             end;
-         else
-          begin
-            internalerror(12121);
-          end;
-         end;
-      end;
-
-
     procedure ti386typeconvnode.second_class_to_intf;
       var
          hreg : tregister;
@@ -1208,14 +849,14 @@ implementation
          secondconvert : array[tconverttype] of pointer = (
            @ti386typeconvnode.second_nothing, {equal}
            @ti386typeconvnode.second_nothing, {not_possible}
-           @ti386typeconvnode.second_string_to_string,
+           @ti386typeconvnode.second_nothing, {second_string_to_string, handled in resulttype pass }
            @ti386typeconvnode.second_char_to_string,
-           @ti386typeconvnode.second_pchar_to_string,
+           @ti386typeconvnode.second_nothing, { pchar_to_string, handled in resulttype pass }
            @ti386typeconvnode.second_nothing, {cchar_to_pchar}
            @ti386typeconvnode.second_cstring_to_pchar,
            @ti386typeconvnode.second_ansistring_to_pchar,
            @ti386typeconvnode.second_string_to_chararray,
-           @ti386typeconvnode.second_chararray_to_string,
+           @ti386typeconvnode.second_nothing, { chararray_to_string, handled in resulttype pass }
            @ti386typeconvnode.second_array_to_pointer,
            @ti386typeconvnode.second_pointer_to_array,
            @ti386typeconvnode.second_int_to_int,
@@ -1425,7 +1066,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.20  2001-08-26 13:36:57  florian
+  Revision 1.21  2001-08-28 13:24:47  jonas
+    + compilerproc implementation of most string-related type conversions
+    - removed all code from the compiler which has been replaced by
+      compilerproc implementations (using {$ifdef hascompilerproc} is not
+      necessary in the compiler)
+
+  Revision 1.20  2001/08/26 13:36:57  florian
     * some cg reorganisation
     * some PPC updates
 

+ 7 - 838
compiler/i386/n386inl.pas

@@ -79,105 +79,6 @@ implementation
                               TI386INLINENODE
 *****************************************************************************}
 
-{$ifndef hascompilerproc}
-    procedure StoreDirectFuncResult(var dest:tnode);
-      var
-        hp : tnode;
-        htype : ttype;
-        hreg : tregister;
-        hregister : tregister;
-        oldregisterdef : boolean;
-        op : tasmop;
-        opsize : topsize;
-
-      begin
-        { Get the accumulator first so it can't be used in the dest }
-        if (dest.resulttype.def.deftype=orddef) and
-          not(is_64bitint(dest.resulttype.def)) then
-          hregister:=getexplicitregister32(accumulator);
-        { process dest }
-        SecondPass(dest);
-        if Codegenerror then
-         exit;
-        { store the value }
-        Case dest.resulttype.def.deftype of
-          floatdef:
-            if dest.location.loc=LOC_CFPUREGISTER then
-              begin
-                 floatstoreops(tfloatdef(dest.resulttype.def).typ,op,opsize);
-                 emit_reg(op,opsize,correct_fpuregister(dest.location.register,fpuvaroffset+1));
-              end
-            else
-              begin
-                 inc(fpuvaroffset);
-                 floatstore(tfloatdef(dest.resulttype.def).typ,dest.location.reference);
-                 { floatstore decrements the fpu var offset }
-                 { but in fact we didn't increment it       }
-              end;
-          orddef:
-            begin
-              if is_64bitint(dest.resulttype.def) then
-                begin
-                   emit_movq_reg_loc(R_EDX,R_EAX,dest.location);
-                end
-              else
-               begin
-                 Case dest.resulttype.def.size of
-                  1 : hreg:=regtoreg8(hregister);
-                  2 : hreg:=regtoreg16(hregister);
-                  4 : hreg:=hregister;
-                 End;
-                 emit_mov_reg_loc(hreg,dest.location);
-                 If (cs_check_range in aktlocalswitches) and
-                    {no need to rangecheck longints or cardinals on 32bit processors}
-                    not((torddef(dest.resulttype.def).typ = s32bit) and
-                        (torddef(dest.resulttype.def).low = longint($80000000)) and
-                        (torddef(dest.resulttype.def).high = $7fffffff)) and
-                    not((torddef(dest.resulttype.def).typ = u32bit) and
-                        (torddef(dest.resulttype.def).low = 0) and
-                        (torddef(dest.resulttype.def).high = longint($ffffffff))) then
-                  Begin
-                    {do not register this temporary def}
-                    OldRegisterDef := RegisterDef;
-                    RegisterDef := False;
-                    htype.reset;
-                    Case torddef(dest.resulttype.def).typ of
-                      u8bit,u16bit,u32bit:
-                        begin
-                          htype.setdef(torddef.create(u32bit,0,longint($ffffffff)));
-                          hreg:=hregister;
-                        end;
-                      s8bit,s16bit,s32bit:
-                        begin
-                          htype.setdef(torddef.create(s32bit,longint($80000000),$7fffffff));
-                          hreg:=hregister;
-                        end;
-                    end;
-                    { create a fake node }
-                    hp := cnothingnode.create;
-                    hp.location.loc := LOC_REGISTER;
-                    hp.location.register := hreg;
-                    if assigned(htype.def) then
-                      hp.resulttype:=htype
-                    else
-                      hp.resulttype:=dest.resulttype;
-                    { emit the range check }
-                    emitrangecheck(hp,dest.resulttype.def);
-                    if assigned(htype.def) then
-                      htype.def.free;
-                    RegisterDef := OldRegisterDef;
-                    hp.free;
-                  End;
-                 ungetregister(hregister);
-               end;
-            End;
-          else
-            internalerror(66766766);
-        end;
-        { free used registers }
-        del_locref(dest.location);
-      end;
-{$endif not hascomppilerproc}
 
     procedure ti386inlinenode.pass_2;
        const
@@ -198,711 +99,6 @@ implementation
          addvalue : longint;
          hp : tnode;
 
-{$ifndef hascompilerproc}
-      procedure handlereadwrite(doread,doln : boolean);
-      { produces code for READ(LN) and WRITE(LN) }
-
-        procedure loadstream;
-          const
-            io:array[boolean] of string[6]=('OUTPUT','INPUT');
-          var
-            r : preference;
-          begin
-            new(r);
-            reset_reference(r^);
-            r^.symbol:=newasmsymbol(
-            'U_SYSTEM_'+io[doread]);
-            getexplicitregister32(R_EDI);
-            emit_ref_reg(A_LEA,S_L,r,R_EDI)
-          end;
-
-        const
-           rdwrprefix:array[boolean] of string[15]=('FPC_WRITE_TEXT_','FPC_READ_TEXT_');
-        var
-           node       : tcallparanode;
-           hp         : tnode;
-           typedtyp,
-           pararesult : tdef;
-           orgfloattype : tfloattype;
-           dummycoll  : tparaitem;
-           iolabel    : tasmlabel;
-           npara      : longint;
-           esireloaded : boolean;
-        label
-          myexit;
-        begin
-           { here we don't use register calling conventions }
-           dummycoll:=TParaItem.Create;
-           dummycoll.register:=R_NO;
-           { I/O check }
-           if (cs_check_io in aktlocalswitches) and
-              not(po_iocheck in aktprocsym.definition.procoptions) then
-             begin
-                getaddrlabel(iolabel);
-                emitlab(iolabel);
-             end
-           else
-             iolabel:=nil;
-           { for write of real with the length specified }
-           hp:=nil;
-           { reserve temporary pointer to data variable }
-           aktfile.symbol:=nil;
-           gettempofsizereference(4,aktfile);
-           { first state text data }
-           ft:=ft_text;
-           { and state a parameter ? }
-           if left=nil then
-             begin
-                { the following instructions are for "writeln;" }
-                loadstream;
-                { save @aktfile in temporary variable }
-                emit_reg_ref(A_MOV,S_L,R_EDI,newreference(aktfile));
-                ungetregister32(R_EDI);
-             end
-           else
-             begin
-                { revers paramters }
-                node:=tcallparanode(reversparameter(left));
-
-                left := node;
-                npara := nb_para;
-                { calculate data variable }
-                { is first parameter a file type ? }
-                if node.left.resulttype.def.deftype=filedef then
-                  begin
-                     ft:=tfiledef(node.left.resulttype.def).filetyp;
-                     if ft=ft_typed then
-                       typedtyp:=tfiledef(node.left.resulttype.def).typedfiletype.def;
-                     secondpass(node.left);
-                     if codegenerror then
-                       goto myexit;
-
-                     { save reference in temporary variables }
-                     if node.left.location.loc<>LOC_REFERENCE then
-                       begin
-                          CGMessage(cg_e_illegal_expression);
-                          goto myexit;
-                       end;
-                     getexplicitregister32(R_EDI);
-                     emit_ref_reg(A_LEA,S_L,newreference(node.left.location.reference),R_EDI);
-                     del_reference(node.left.location.reference);
-                     { skip to the next parameter }
-                     node:=tcallparanode(node.right);
-                  end
-                else
-                  begin
-                  { load stdin/stdout stream }
-                     loadstream;
-                  end;
-
-                { save @aktfile in temporary variable }
-                emit_reg_ref(A_MOV,S_L,R_EDI,newreference(aktfile));
-                ungetregister32(R_EDI);
-                if doread then
-                { parameter by READ gives call by reference }
-                  dummycoll.paratyp:=vs_var
-                { an WRITE Call by "Const" }
-                else
-                  dummycoll.paratyp:=vs_const;
-
-                { because of secondcallparan, which otherwise attaches }
-                if ft=ft_typed then
-                  { this is to avoid copy of simple const parameters }
-                  {dummycoll.data:=new(pformaldef.create)}
-                  dummycoll.paratype:=cformaltype
-                else
-                  { I think, this isn't a good solution (FK) }
-                  dummycoll.paratype.reset;
-
-                while assigned(node) do
-                  begin
-                     esireloaded:=false;
-                     pushusedregisters(pushed,$ff);
-                     hp:=node;
-                     node:=tcallparanode(node.right);
-                     tcallparanode(hp).right:=nil;
-                     if cpf_is_colon_para in tcallparanode(hp).callparaflags then
-                       CGMessage(parser_e_illegal_colon_qualifier);
-                     { when float is written then we need bestreal to be pushed
-                       convert here else we loose the old float type }
-                     if (not doread) and
-                        (ft<>ft_typed) and
-                        (tcallparanode(hp).left.resulttype.def.deftype=floatdef) then
-                      begin
-                        orgfloattype:=tfloatdef(tcallparanode(hp).left.resulttype.def).typ;
-                        tcallparanode(hp).left:=ctypeconvnode.create(tcallparanode(hp).left,pbestrealtype^);
-                        firstpass(tcallparanode(hp).left);
-                      end;
-                     { when read ord,floats are functions, so they need this
-                       parameter as their destination instead of being pushed }
-                     if doread and
-                        (ft<>ft_typed) and
-                        (tcallparanode(hp).resulttype.def.deftype in [orddef,floatdef]) then
-                      begin
-                      end
-                     else
-                      begin
-                        if ft=ft_typed then
-                          never_copy_const_param:=true;
-                        { reset data type }
-                        dummycoll.paratype.reset;
-                        { create temporary defs for high tree generation }
-                        if doread and (is_shortstring(tcallparanode(hp).resulttype.def)) then
-                          dummycoll.paratype:=openshortstringtype
-                        else
-                          if (is_chararray(tcallparanode(hp).resulttype.def)) then
-                            dummycoll.paratype:=openchararraytype;
-                        tcallparanode(hp).secondcallparan(dummycoll,false,false,false,0,0);
-                        if ft=ft_typed then
-                          never_copy_const_param:=false;
-                      end;
-                     tcallparanode(hp).right:=node;
-                     if codegenerror then
-                       goto myexit;
-
-                     emit_push_mem(aktfile);
-                     if (ft=ft_typed) then
-                       begin
-                          { OK let's try this }
-                          { first we must only allow the right type }
-                          { we have to call blockread or blockwrite }
-                          { but the real problem is that            }
-                          { reset and rewrite should have set       }
-                          { the type size                          }
-                          { as recordsize for that file !!!!    }
-                          { how can we make that                    }
-                          { I think that is only possible by adding }
-                          { reset and rewrite to the inline list a call }
-                          { allways read only one record by element }
-                            push_int(typedtyp.size);
-                            saveregvars($ff);
-                            if doread then
-                              emitcall('FPC_TYPED_READ')
-                            else
-                              emitcall('FPC_TYPED_WRITE');
-                       end
-                     else
-                       begin
-                          { save current position }
-                          pararesult:=tcallparanode(hp).left.resulttype.def;
-                          { handle possible field width  }
-                          { of course only for write(ln) }
-                          if not doread then
-                            begin
-                               { handle total width parameter }
-                              if assigned(node) and (cpf_is_colon_para in node.callparaflags) then
-                                begin
-                                   hp:=node;
-                                   node:=tcallparanode(node.right);
-                                   tcallparanode(hp).right:=nil;
-                                   dummycoll.paratype.setdef(hp.resulttype.def);
-                                   dummycoll.paratyp:=vs_value;
-                                   tcallparanode(hp).secondcallparan(dummycoll,false,false,false,0,0);
-                                   tcallparanode(hp).right:=node;
-                                   if codegenerror then
-                                     goto myexit;
-                                end
-                              else
-                                if pararesult.deftype<>floatdef then
-                                  push_int(0)
-                                else
-                                  push_int(-32767);
-                            { a second colon para for a float ? }
-                              if assigned(node) and (cpf_is_colon_para in node.callparaflags) then
-                                begin
-                                   hp:=node;
-                                   node:=tcallparanode(node.right);
-                                   tcallparanode(hp).right:=nil;
-                                   dummycoll.paratype.setdef(hp.resulttype.def);
-                                   dummycoll.paratyp:=vs_value;
-                                   tcallparanode(hp).secondcallparan(dummycoll,false,false,false,0,0);
-                                   tcallparanode(hp).right:=node;
-                                   if pararesult.deftype<>floatdef then
-                                     CGMessage(parser_e_illegal_colon_qualifier);
-                                   if codegenerror then
-                                     goto myexit;
-                                end
-                              else
-                                begin
-                                  if pararesult.deftype=floatdef then
-                                    push_int(-1);
-                                end;
-                             { push also the real type for floats }
-                              if pararesult.deftype=floatdef then
-                                push_int(ord(orgfloattype));
-                            end;
-                          saveregvars($ff);
-                          case pararesult.deftype of
-                            stringdef :
-                              begin
-                                emitcall(rdwrprefix[doread]+tstringdef(pararesult).stringtypname);
-                              end;
-                            pointerdef :
-                              begin
-                                if is_pchar(pararesult) then
-                                  emitcall(rdwrprefix[doread]+'PCHAR_AS_POINTER')
-                              end;
-                            arraydef :
-                              begin
-                                if is_chararray(pararesult) then
-                                  emitcall(rdwrprefix[doread]+'PCHAR_AS_ARRAY')
-                              end;
-                            floatdef :
-                              begin
-                                emitcall(rdwrprefix[doread]+'FLOAT');
-                                {
-                                if tfloatdef(resulttype.def).typ<>f32bit then
-                                  dec(fpuvaroffset);
-                                }
-                                if doread then
-                                  begin
-                                     maybe_loadself;
-                                     esireloaded:=true;
-                                     StoreDirectFuncResult(tcallparanode(hp).left);
-                                  end;
-                              end;
-                            orddef :
-                              begin
-                                case torddef(pararesult).typ of
-                                  s8bit,s16bit,s32bit :
-                                    emitcall(rdwrprefix[doread]+'SINT');
-                                  u8bit,u16bit,u32bit :
-                                    emitcall(rdwrprefix[doread]+'UINT');
-                                  uchar :
-                                    emitcall(rdwrprefix[doread]+'CHAR');
-                                  uwidechar :
-                                    emitcall(rdwrprefix[doread]+'WIDECHAR');
-                                  s64bit :
-                                    emitcall(rdwrprefix[doread]+'INT64');
-                                  u64bit :
-                                    emitcall(rdwrprefix[doread]+'QWORD');
-                                  bool8bit,
-                                  bool16bit,
-                                  bool32bit :
-                                    emitcall(rdwrprefix[doread]+'BOOLEAN');
-                                end;
-                                if doread then
-                                  begin
-                                     maybe_loadself;
-                                     esireloaded:=true;
-                                     StoreDirectFuncResult(tcallparanode(hp).left);
-                                  end;
-                              end;
-                          end;
-                       end;
-                   { load ESI in methods again }
-                     popusedregisters(pushed);
-                     if not(esireloaded) then
-                       maybe_loadself;
-                  end;
-             end;
-         { Insert end of writing for textfiles }
-           if ft=ft_text then
-             begin
-               pushusedregisters(pushed,$ff);
-               emit_push_mem(aktfile);
-               saveregvars($ff);
-               if doread then
-                begin
-                  if doln then
-                    emitcall('FPC_READLN_END')
-                  else
-                    emitcall('FPC_READ_END');
-                end
-               else
-                begin
-                  if doln then
-                    emitcall('FPC_WRITELN_END')
-                  else
-                    emitcall('FPC_WRITE_END');
-                end;
-               popusedregisters(pushed);
-               maybe_loadself;
-             end;
-         { Insert IOCheck if set }
-           if assigned(iolabel) then
-             begin
-                { registers are saved in the procedure }
-                emit_sym(A_PUSH,S_L,iolabel);
-                emitcall('FPC_IOCHECK');
-             end;
-         { Freeup all used temps }
-           ungetiftemp(aktfile);
-           if assigned(left) then
-             begin
-                left:=reversparameter(left);
-                if npara<>nb_para then
-                  CGMessage(cg_f_internal_error_in_secondinline);
-                hp:=left;
-                while assigned(hp) do
-                  begin
-                     if assigned(tcallparanode(hp).left) then
-                       if (tcallparanode(hp).left.location.loc in [LOC_MEM,LOC_REFERENCE]) then
-                         ungetiftemp(tcallparanode(hp).left.location.reference);
-                     hp:=tcallparanode(hp).right;
-                  end;
-             end;
-
-        myexit:
-           dummycoll.free;
-        end;
-
-      procedure handle_str;
-
-        var
-           hp,
-           node : tcallparanode;
-           dummycoll : tparaitem;
-           //hp2 : tstringconstnode;
-           is_real : boolean;
-           realtype : tfloattype;
-           procedureprefix : string;
-        label
-           myexit;
-          begin
-           dummycoll:=TParaItem.Create;
-           dummycoll.register:=R_NO;
-           pushusedregisters(pushed,$ff);
-           node:=tcallparanode(left);
-           is_real:=false;
-           while assigned(node.right) do node:=tcallparanode(node.right);
-           { if a real parameter somewhere then call REALSTR }
-           if (node.left.resulttype.def.deftype=floatdef) then
-            begin
-              is_real:=true;
-              realtype:=tfloatdef(node.left.resulttype.def).typ;
-            end;
-
-           node:=tcallparanode(left);
-           { we have at least two args }
-           { with at max 2 colon_para in between }
-
-           { string arg }
-           hp:=node;
-           node:=tcallparanode(node.right);
-           hp.right:=nil;
-           dummycoll.paratyp:=vs_var;
-           if is_shortstring(hp.resulttype.def) then
-             dummycoll.paratype:=openshortstringtype
-           else
-             dummycoll.paratype:=hp.resulttype;
-           procedureprefix:='FPC_'+tstringdef(hp.resulttype.def).stringtypname+'_';
-           tcallparanode(hp).secondcallparan(dummycoll,false,false,false,0,0);
-           if codegenerror then
-            goto myexit;
-
-           dummycoll.paratyp:=vs_const;
-           left.free;
-           left:=nil;
-           { second arg }
-           hp:=node;
-           node:=tcallparanode(node.right);
-           hp.right:=nil;
-
-           { if real push real type }
-           if is_real then
-             push_int(ord(realtype));
-
-           { frac  para }
-           if (cpf_is_colon_para in hp.callparaflags) and assigned(node) and
-              (cpf_is_colon_para in node.callparaflags) then
-             begin
-                dummycoll.paratype.setdef(hp.resulttype.def);
-                dummycoll.paratyp:=vs_value;
-                tcallparanode(hp).secondcallparan(dummycoll,false,false,false,0,0);
-                if codegenerror then
-                  goto myexit;
-                hp.free;
-                hp:=node;
-                node:=tcallparanode(node.right);
-                hp.right:=nil;
-             end
-           else
-             if is_real then
-             push_int(-1);
-
-           { third arg, length only if is_real }
-           if (cpf_is_colon_para in hp.callparaflags) then
-             begin
-                dummycoll.paratype.setdef(hp.resulttype.def);
-                dummycoll.paratyp:=vs_value;
-                tcallparanode(hp).secondcallparan(dummycoll,false,false,false,0,0);
-                if codegenerror then
-                  goto myexit;
-                hp.free;
-                hp:=node;
-                node:=tcallparanode(node.right);
-                hp.right:=nil;
-             end
-           else
-             if is_real then
-               push_int(-32767)
-             else
-               push_int(-1);
-
-           { Convert float to bestreal }
-           if is_real then
-            begin
-              hp.left:=ctypeconvnode.create(hp.left,pbestrealtype^);
-              firstpass(hp.left);
-            end;
-
-           { last arg longint or real }
-           dummycoll.paratype.setdef(hp.resulttype.def);
-           dummycoll.paratyp:=vs_value;
-           tcallparanode(hp).secondcallparan(dummycoll,false,false,false,0,0);
-           if codegenerror then
-            goto myexit;
-
-           saveregvars($ff);
-           if is_real then
-             emitcall(procedureprefix+'FLOAT')
-           else
-             case torddef(hp.resulttype.def).typ of
-                u32bit:
-                  emitcall(procedureprefix+'CARDINAL');
-
-                u64bit:
-                  emitcall(procedureprefix+'QWORD');
-
-                s64bit:
-                  emitcall(procedureprefix+'INT64');
-
-                else
-                  emitcall(procedureprefix+'LONGINT');
-             end;
-           popusedregisters(pushed);
-           hp.free;
-
-        myexit:
-           dummycoll.free;
-        end;
-
-        Procedure Handle_Val;
-        var
-           hp,node,
-           code_para, dest_para : tcallparanode;
-           hreg,hreg2: TRegister;
-           hdef: torddef;
-           procedureprefix : string;
-           hr, hr2: TReference;
-           dummycoll : tparaitem;
-           has_code, has_32bit_code, oldregisterdef: boolean;
-           r : preference;
-          label
-            myexit;
-          begin
-           dummycoll:=TParaItem.Create;
-           dummycoll.register:=R_NO;
-           node:=tcallparanode(left);
-           hp:=node;
-           node:=tcallparanode(node.right);
-           hp.right:=nil;
-          {if we have 3 parameters, we have a code parameter}
-           has_code := Assigned(node.right);
-           has_32bit_code := false;
-           reset_reference(hr);
-           hreg := R_NO;
-
-           If has_code then
-             Begin
-               {code is an orddef, that's checked in tcinl}
-               code_para := hp;
-               hp := node;
-               node := tcallparanode(node.right);
-               hp.right := nil;
-               has_32bit_code := (torddef(tcallparanode(code_para).left.resulttype.def).typ in [u32bit,s32bit]);
-             End;
-
-          {hp = destination now, save for later use}
-           dest_para := hp;
-
-          {if EAX is already in use, it's a register variable. Since we don't
-           need another register besides EAX, release the one we got}
-           If hreg <> R_EAX Then ungetregister32(hreg);
-
-          {load and push the address of the destination}
-           dummycoll.paratyp:=vs_var;
-           dummycoll.paratype.setdef(dest_para.resulttype.def);
-           dest_para.secondcallparan(dummycoll,false,false,false,0,0);
-           if codegenerror then
-            goto myexit;
-
-          {save the regvars}
-           pushusedregisters(pushed,$ff);
-
-          {now that we've already pushed the addres of dest_para.left on the
-           stack, we can put the real parameters on the stack}
-
-           If has_32bit_code Then
-             Begin
-               dummycoll.paratyp:=vs_var;
-               dummycoll.paratype.setdef(code_para.resulttype.def);
-               code_para.secondcallparan(dummycoll,false,false,false,0,0);
-               if codegenerror then
-                goto myexit;
-               code_para.free;
-             End
-           Else
-             Begin
-           {only 32bit code parameter is supported, so fake one}
-               GetTempOfSizeReference(4,hr);
-               emitpushreferenceaddr(hr);
-             End;
-
-          {node = first parameter = string}
-           dummycoll.paratyp:=vs_const;
-           dummycoll.paratype.setdef(node.resulttype.def);
-           node.secondcallparan(dummycoll,false,false,false,0,0);
-           if codegenerror then
-             goto myexit;
-
-           Case dest_para.resulttype.def.deftype of
-             floatdef:
-               begin
-                  procedureprefix := 'FPC_VAL_REAL_';
-                  inc(fpuvaroffset);
-               end;
-             orddef:
-               if is_64bitint(dest_para.resulttype.def) then
-                 begin
-                    if is_signed(dest_para.resulttype.def) then
-                      procedureprefix := 'FPC_VAL_INT64_'
-                    else
-                      procedureprefix := 'FPC_VAL_QWORD_';
-                 end
-               else
-                 begin
-                    if is_signed(dest_para.resulttype.def) then
-                      begin
-                        {if we are converting to a signed number, we have to include the
-                         size of the destination, so the Val function can extend the sign
-                         of the result to allow proper range checking}
-                        emit_const(A_PUSH,S_L,dest_para.resulttype.def.size);
-                        procedureprefix := 'FPC_VAL_SINT_'
-                      end
-                    else
-                      procedureprefix := 'FPC_VAL_UINT_';
-                 end;
-           End;
-
-           saveregvars($ff);
-           emitcall(procedureprefix+tstringdef(node.resulttype.def).stringtypname);
-           { before disposing node we need to ungettemp !! PM }
-           if node.left.location.loc in [LOC_REFERENCE,LOC_MEM] then
-             ungetiftemp(node.left.location.reference);
-           node.free;
-           left := nil;
-
-          {reload esi in case the dest_para/code_para is a class variable or so}
-           maybe_loadself;
-
-           If (dest_para.resulttype.def.deftype = orddef) Then
-             Begin
-              {store the result in a safe place, because EAX may be used by a
-               register variable}
-               hreg := getexplicitregister32(R_EAX);
-               emit_reg_reg(A_MOV,S_L,R_EAX,hreg);
-               if is_64bitint(dest_para.resulttype.def) then
-                 begin
-                    hreg2:=getexplicitregister32(R_EDX);
-                    emit_reg_reg(A_MOV,S_L,R_EDX,hreg2);
-                 end;
-              {as of now, hreg now holds the location of the result, if it was
-               integer}
-             End;
-
-           { restore the register vars}
-
-           popusedregisters(pushed);
-
-           If has_code and Not(has_32bit_code) Then
-             {only 16bit code is possible}
-             Begin
-              {load the address of the code parameter}
-               secondpass(code_para.left);
-              {move the code to its destination}
-               getexplicitregister32(R_EDI);
-               emit_ref_reg(A_MOV,S_L,NewReference(hr),R_EDI);
-               emit_mov_reg_loc(R_DI,code_para.left.location);
-               ungetregister32(R_EDI);
-               code_para.free;
-             End;
-
-          {restore the address of the result}
-           getexplicitregister32(R_EDI);
-           emit_reg(A_POP,S_L,R_EDI);
-
-          {set up hr2 to a refernce with EDI as base register}
-           reset_reference(hr2);
-           hr2.base := R_EDI;
-
-          {save the function result in the destination variable}
-           Case dest_para.left.resulttype.def.deftype of
-             floatdef:
-               floatstore(tfloatdef(dest_para.left.resulttype.def).typ, hr2);
-             orddef:
-               Case torddef(dest_para.left.resulttype.def).typ of
-                 u8bit,s8bit:
-                   emit_reg_ref(A_MOV, S_B,
-                     RegToReg8(hreg),newreference(hr2));
-                 u16bit,s16bit:
-                   emit_reg_ref(A_MOV, S_W,
-                     RegToReg16(hreg),newreference(hr2));
-                 u32bit,s32bit:
-                   emit_reg_ref(A_MOV, S_L,
-                     hreg,newreference(hr2));
-                 u64bit,s64bit:
-                   begin
-                      emit_reg_ref(A_MOV, S_L,
-                        hreg,newreference(hr2));
-                      r:=newreference(hr2);
-                      inc(r^.offset,4);
-                      emit_reg_ref(A_MOV, S_L,
-                        hreg2,r);
-                   end;
-               End;
-           End;
-           ungetregister32(R_EDI);
-           If (cs_check_range in aktlocalswitches) and
-              (dest_para.left.resulttype.def.deftype = orddef) and
-              (not(is_64bitint(dest_para.left.resulttype.def))) and
-            {the following has to be changed to 64bit checking, once Val
-             returns 64 bit values (unless a special Val function is created
-             for that)}
-            {no need to rangecheck longints or cardinals on 32bit processors}
-               not((torddef(dest_para.left.resulttype.def).typ = s32bit) and
-                   (torddef(dest_para.left.resulttype.def).low = longint($80000000)) and
-                   (torddef(dest_para.left.resulttype.def).high = $7fffffff)) and
-               not((torddef(dest_para.left.resulttype.def).typ = u32bit) and
-                   (torddef(dest_para.left.resulttype.def).low = 0) and
-                   (torddef(dest_para.left.resulttype.def).high = longint($ffffffff))) then
-             Begin
-               hp:=tcallparanode(dest_para.left.getcopy);
-               hp.location.loc := LOC_REGISTER;
-               hp.location.register := hreg;
-              {do not register this temporary def}
-               OldRegisterDef := RegisterDef;
-               RegisterDef := False;
-               Case torddef(dest_para.left.resulttype.def).typ of
-                 u8bit,u16bit,u32bit: hdef:=torddef.create(u32bit,0,longint($ffffffff));
-                 s8bit,s16bit,s32bit: hdef:=torddef.create(s32bit,longint($80000000),$7fffffff);
-               end;
-               hp.resulttype.def := hdef;
-               emitrangecheck(hp,dest_para.left.resulttype.def);
-               hp.right := nil;
-               hp.resulttype.def.free;
-               RegisterDef := OldRegisterDef;
-               hp.free;
-             End;
-          {dest_para.right is already nil}
-           dest_para.free;
-           UnGetIfTemp(hr);
-        myexit:
-           dummycoll.free;
-        end;
-{$endif not hascompilerproc}
-
       var
          r : preference;
          //hp : tcallparanode;
@@ -1388,21 +584,8 @@ implementation
               end;
              in_reset_typedfile,in_rewrite_typedfile :
                begin
-{$ifndef hascompilerproc}
-                  pushusedregisters(pushed,$ff);
-                  emit_const(A_PUSH,S_L,tfiledef(left.resulttype.def).typedfiletype.def.size);
-                  secondpass(left);
-                  emitpushreferenceaddr(left.location.reference);
-                  saveregvars($ff);
-                  if inlinenumber=in_reset_typedfile then
-                    emitcall('FPC_RESET_TYPED')
-                  else
-                    emitcall('FPC_REWRITE_TYPED');
-                  popusedregisters(pushed);
-{$else not hascompilerproc}
                   { should be removed in pass_1 (JM) }
                   internalerror(200108132);
-{$endif not hascompilerproc}
                end;
             in_setlength_x:
                begin
@@ -1491,41 +674,21 @@ implementation
                     end;
                   popusedregisters(pushed);
                end;
-{$ifndef hascompilerproc}
-            in_write_x :
-              handlereadwrite(false,false);
-            in_writeln_x :
-              handlereadwrite(false,true);
-            in_read_x :
-              handlereadwrite(true,false);
-            in_readln_x :
-              handlereadwrite(true,true);
-{$else hascomppilerproc}
               in_read_x,
               in_readln_x,
               in_write_x,
               in_writeln_x :
                 { should be removed in the resulttype pass already (JM) }
                 internalerror(200108162);
-{$endif not hascomppilerproc}
             in_str_x_string :
               begin
-{$ifndef hascompilerproc}
-                 handle_str;
-                 maybe_loadself;
-{$else not hascompilerproc}
                  { should be removed in det_resulttype (JM) }
                  internalerror(200108131);
-{$endif not hascompilerproc}
               end;
             in_val_x :
               Begin
-{$ifdef hascompilerproc}
                  { should be removed in det_resulttype (JM) }
                  internalerror(200108241);
-{$else hascompilerproc}
-                handle_val;
-{$endif hascompilerproc}
               End;
             in_include_x_y,
             in_exclude_x_y:
@@ -1719,7 +882,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.21  2001-08-26 13:36:58  florian
+  Revision 1.22  2001-08-28 13:24:47  jonas
+    + compilerproc implementation of most string-related type conversions
+    - removed all code from the compiler which has been replaced by
+      compilerproc implementations (using {$ifdef hascompilerproc} is not
+      necessary in the compiler)
+
+  Revision 1.21  2001/08/26 13:36:58  florian
     * some cg reorganisation
     * some PPC updates
 

+ 11 - 6
compiler/ncal.pas

@@ -44,9 +44,7 @@ interface
           { only the processor specific nodes need to override this }
           { constructor                                             }
           constructor create(l:tnode; v : tprocsym;st : tsymtable; mp : tnode);virtual;
-{$ifdef hascompilerproc}
           constructor createintern(const name: string; params: tnode);
-{$endif hascompilerproc}
           destructor destroy;override;
           function  getcopy : tnode;override;
           procedure insertintolist(l : tnodelist);override;
@@ -562,7 +560,6 @@ implementation
          procdefinition:=nil;
       end;
 
-{$ifdef hascompilerproc}
      constructor tcallnode.createintern(const name: string; params: tnode);
        var
          srsym: tsym;
@@ -581,10 +578,12 @@ implementation
            end;
          if not assigned(srsym) or
             (srsym.typ <> procsym) then
-           internalerror(200107271);
+           begin
+             writeln('unknown compilerproc ',name);
+             internalerror(200107271);
+           end;
          self.create(params,tprocsym(srsym),symowner,nil);
        end;
-{$endif hascompilerproc}
 
     destructor tcallnode.destroy;
       begin
@@ -1717,7 +1716,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.45  2001-08-26 13:36:39  florian
+  Revision 1.46  2001-08-28 13:24:46  jonas
+    + compilerproc implementation of most string-related type conversions
+    - removed all code from the compiler which has been replaced by
+      compilerproc implementations (using {$ifdef hascompilerproc} is not
+      necessary in the compiler)
+
+  Revision 1.45  2001/08/26 13:36:39  florian
     * some cg reorganisation
     * some PPC updates
 

+ 78 - 28
compiler/ncnv.pas

@@ -42,6 +42,7 @@ interface
           function docompare(p: tnode) : boolean; override;
        private
           function resulttype_cord_to_pointer : tnode;
+          function resulttype_chararray_to_string : tnode;
           function resulttype_string_to_string : tnode;
           function resulttype_char_to_string : tnode;
           function resulttype_int_to_real : tnode;
@@ -50,6 +51,7 @@ interface
           function resulttype_cstring_to_pchar : tnode;
           function resulttype_char_to_char : tnode;
           function resulttype_arrayconstructor_to_set : tnode;
+          function resulttype_pchar_to_string : tnode;
           function resulttype_call_helper(c : tconverttype) : tnode;
        protected
           function first_int_to_int : tnode;virtual;
@@ -62,7 +64,6 @@ interface
           function first_int_to_real : tnode;virtual;
           function first_real_to_real : tnode;virtual;
           function first_pointer_to_array : tnode;virtual;
-          function first_chararray_to_string : tnode;virtual;
           function first_cchar_to_pchar : tnode;virtual;
           function first_bool_to_int : tnode;virtual;
           function first_int_to_bool : tnode;virtual;
@@ -70,7 +71,6 @@ interface
           function first_proc_to_procvar : tnode;virtual;
           function first_load_smallset : tnode;virtual;
           function first_cord_to_pointer : tnode;virtual;
-          function first_pchar_to_string : tnode;virtual;
           function first_ansistring_to_pchar : tnode;virtual;
           function first_arrayconstructor_to_set : tnode;virtual;
           function first_class_to_intf : tnode;virtual;
@@ -104,7 +104,7 @@ implementation
       globtype,systems,tokens,
       cutils,verbose,globals,widestr,
       symconst,symdef,symsym,symtable,
-      ncon,ncal,nset,nadd,
+      ncon,ncal,nset,nadd,ninl,
       cgbase,
       htypechk,pass_1,cpubase,cpuinfo;
 
@@ -421,9 +421,20 @@ implementation
           internalerror(200104023);
       end;
 
-
+    function ttypeconvnode.resulttype_chararray_to_string : tnode;
+      begin
+        result := ccallnode.createintern(
+          'fpc_chararray_to_'+lower(tstringdef(resulttype.def).stringtypname),
+          ccallparanode.create(left,nil));
+        left := nil;
+        resulttypepass(result);
+      end;
+    
+    
     function ttypeconvnode.resulttype_string_to_string : tnode;
       var
+        procname: string[31];
+        stringpara : tcallparanode;
         pw : pcompilerwidestring;
         pc : pchar;
       begin
@@ -454,12 +465,36 @@ implementation
              tstringconstnode(left).resulttype:=resulttype;
              result:=left;
              left:=nil;
-          end;
+          end
+         else
+           begin
+             { get the correct procedure name }
+             procname := 'fpc_'+
+               lower(tstringdef(left.resulttype.def).stringtypname+
+               '_to_'+tstringdef(resulttype.def).stringtypname);
+
+             { create parameter (and remove left node from typeconvnode }
+             { since it's reused as parameter)                          }
+             stringpara := ccallparanode.create(left,nil);
+             left := nil;
+
+             { hen converting to shortstrings, we have to pass high(destination) too }
+             if (tstringdef(resulttype.def).string_typ =
+                  st_shortstring) then
+               stringpara.right := ccallparanode.create(cinlinenode.create(
+                 in_high_x,false,self.getcopy),nil);
+                 
+             { and create the callnode }
+             result := ccallnode.createintern(procname,stringpara);
+             resulttypepass(result);
+           end;
       end;
 
 
     function ttypeconvnode.resulttype_char_to_string : tnode;
       var
+         procname: string[31];
+         para : tcallparanode;
          hp : tstringconstnode;
          ws : pcompilerwidestring;
       begin
@@ -477,7 +512,23 @@ implementation
                hp:=cstringconstnode.createstr(chr(tordconstnode(left).value),tstringdef(resulttype.def).string_typ);
               resulttypepass(hp);
               result:=hp;
-           end;
+           end
+         else
+           { shortstrings are handled 'inline' }
+           if tstringdef(resulttype.def).string_typ <> st_shortstring then
+             begin
+               { create the parameter }
+               para := ccallparanode.create(left,nil);
+               left := nil;
+
+               { and the procname }
+               procname := 'fpc_char_to_' +
+                 lower(tstringdef(resulttype.def).stringtypname);
+
+               { and finally the call }
+               result := ccallnode.createintern(procname,para);
+               resulttypepass(result);
+             end;
       end;
 
 
@@ -580,6 +631,16 @@ implementation
       end;
 
 
+    function ttypeconvnode.resulttype_pchar_to_string : tnode;
+      begin
+        result := ccallnode.createintern(
+          'fpc_pchar_to_'+lower(tstringdef(resulttype.def).stringtypname),
+          ccallparanode.create(left,nil));
+        left := nil;
+        resulttypepass(result);
+      end;
+
+
     function ttypeconvnode.resulttype_call_helper(c : tconverttype) : tnode;
 
       const
@@ -588,12 +649,12 @@ implementation
           {not_possible} nil,
           { string_2_string } @ttypeconvnode.resulttype_string_to_string,
           { char_2_string } @ttypeconvnode.resulttype_char_to_string,
-          { pchar_2_string } nil,
+          { pchar_2_string } @ttypeconvnode.resulttype_pchar_to_string,
           { cchar_2_pchar } @ttypeconvnode.resulttype_cchar_to_pchar,
           { cstring_2_pchar } @ttypeconvnode.resulttype_cstring_to_pchar,
           { ansistring_2_pchar } nil,
           { string_2_chararray } nil,
-          { chararray_2_string } nil,
+          { chararray_2_string } @ttypeconvnode.resulttype_chararray_to_string,
           { array_2_pointer } nil,
           { pointer_2_array } nil,
           { int_2_int } nil,
@@ -1093,16 +1154,6 @@ implementation
       end;
 
 
-    function ttypeconvnode.first_chararray_to_string : tnode;
-      begin
-         first_chararray_to_string:=nil;
-         { the only important information is the location of the }
-         { result                                               }
-         { other stuff is done by firsttypeconv           }
-         location.loc:=LOC_MEM;
-      end;
-
-
     function ttypeconvnode.first_cchar_to_pchar : tnode;
       begin
          first_cchar_to_pchar:=nil;
@@ -1181,13 +1232,6 @@ implementation
       end;
 
 
-    function ttypeconvnode.first_pchar_to_string : tnode;
-      begin
-         first_pchar_to_string:=nil;
-         location.loc:=LOC_REFERENCE;
-      end;
-
-
     function ttypeconvnode.first_ansistring_to_pchar : tnode;
       begin
          first_ansistring_to_pchar:=nil;
@@ -1220,12 +1264,12 @@ implementation
            @ttypeconvnode.first_nothing, {not_possible}
            @ttypeconvnode.first_string_to_string,
            @ttypeconvnode.first_char_to_string,
-           @ttypeconvnode.first_pchar_to_string,
+           @ttypeconvnode.first_nothing, { removed in resulttype_chararray_to_string }
            @ttypeconvnode.first_cchar_to_pchar,
            @ttypeconvnode.first_cstring_to_pchar,
            @ttypeconvnode.first_ansistring_to_pchar,
            @ttypeconvnode.first_string_to_chararray,
-           @ttypeconvnode.first_chararray_to_string,
+           @ttypeconvnode.first_nothing, { removed in resulttype_chararray_to_string }
            @ttypeconvnode.first_array_to_pointer,
            @ttypeconvnode.first_pointer_to_array,
            @ttypeconvnode.first_int_to_int,
@@ -1433,7 +1477,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.32  2001-08-26 13:36:40  florian
+  Revision 1.33  2001-08-28 13:24:46  jonas
+    + compilerproc implementation of most string-related type conversions
+    - removed all code from the compiler which has been replaced by
+      compilerproc implementations (using {$ifdef hascompilerproc} is not
+      necessary in the compiler)
+
+  Revision 1.32  2001/08/26 13:36:40  florian
     * some cg reorganisation
     * some PPC updates
 

+ 7 - 411
compiler/ninl.pas

@@ -39,13 +39,11 @@ interface
           function pass_1 : tnode;override;
           function det_resulttype:tnode;override;
           function docompare(p: tnode): boolean; override;
-{$ifdef hascompilerproc}
         private
           function handle_str: tnode;
           function handle_reset_rewrite_typed: tnode;
           function handle_read_write: tnode;
           function handle_val: tnode;
-{$endif hascompilerproc}
        end;
 
     var
@@ -94,8 +92,6 @@ implementation
       end;
 
 
-{$ifdef hascompilerproc}
-
       function tinlinenode.handle_str : tnode;
       var
         lenpara,
@@ -968,7 +964,6 @@ implementation
         { and return it }
         result := newblock;
       end;
-{$endif hascompilerproc}
 
 
 
@@ -1645,183 +1640,7 @@ implementation
               in_write_x,
               in_writeln_x :
                 begin
-{$ifdef hascompilerproc}
                   result := handle_read_write;
-{$else hascompilerproc}
-                  resulttype:=voidtype;
-               { we must know if it is a typed file or not }
-               { but we must first do the firstpass for it }
-               file_is_typed:=false;
-               if assigned(left) then
-                 begin
-                    iswrite:=(inlinenumber in [in_write_x,in_writeln_x]);
-                    set_varstate(left,iswrite);
-                    { now we can check }
-                    hp:=left;
-                    while assigned(tcallparanode(hp).right) do
-                      hp:=tcallparanode(hp).right;
-                    { if resulttype.def is not assigned, then automatically }
-                    { file is not typed.                             }
-                    if assigned(hp) and assigned(hp.resulttype.def) then
-                      Begin
-                        if (hp.resulttype.def.deftype=filedef) then
-                        if (tfiledef(hp.resulttype.def).filetyp=ft_untyped) then
-                          begin
-                           if (inlinenumber in [in_readln_x,in_writeln_x]) then
-                             CGMessage(type_e_no_readln_writeln_for_typed_file)
-                           else
-                             CGMessage(type_e_no_read_write_for_untyped_file);
-                          end
-                        else if (tfiledef(hp.resulttype.def).filetyp=ft_typed) then
-                         begin
-                           file_is_typed:=true;
-                           { test the type }
-                           if (inlinenumber in [in_readln_x,in_writeln_x]) then
-                             CGMessage(type_e_no_readln_writeln_for_typed_file);
-                           hpp:=left;
-                           while (hpp<>hp) do
-                            begin
-                              if (tcallparanode(hpp).left.nodetype=typen) then
-                                CGMessage(type_e_cant_read_write_type);
-                              if not is_equal(hpp.resulttype.def,tfiledef(hp.resulttype.def).typedfiletype.def) then
-                                CGMessage(type_e_mismatch);
-                              { generate the high() value for the shortstring }
-                              if ((not iswrite) and is_shortstring(tcallparanode(hpp).left.resulttype.def)) or
-                                 (is_chararray(tcallparanode(hpp).left.resulttype.def)) then
-                                tcallparanode(hpp).gen_high_tree(true);
-                              { read(ln) is call by reference (JM) }
-                              { and so is the data param of FPC_TYPED_WRITE (JM) }
-                              if not iswrite or file_is_typed then
-                                make_not_regable(tcallparanode(hpp).left);
-                              hpp:=tcallparanode(hpp).right;
-                            end;
-                         end;
-                      end; { endif assigned(hp) }
-
-                    { insert type conversions for write(ln) }
-                    if (not file_is_typed) then
-                      begin
-                         hp:=left;
-                         while assigned(hp) do
-                           begin
-                             if (tcallparanode(hp).left.nodetype=typen) then
-                               CGMessage(type_e_cant_read_write_type);
-                             if assigned(tcallparanode(hp).left.resulttype.def) then
-                               begin
-                                 isreal:=false;
-                                 { support writeln(procvar) }
-                                 if (tcallparanode(hp).left.resulttype.def.deftype=procvardef) then
-                                  begin
-                                    p1:=ccallnode.create(nil,nil,nil,nil);
-                                    tcallnode(p1).set_procvar(tcallparanode(hp).left);
-                                    resulttypepass(p1);
-                                    tcallparanode(hp).left:=p1;
-                                  end;
-                                 case tcallparanode(hp).left.resulttype.def.deftype of
-                                   filedef :
-                                     begin
-                                       { only allowed as first parameter }
-                                       if assigned(tcallparanode(hp).right) then
-                                         CGMessage(type_e_cant_read_write_type);
-                                     end;
-                                   stringdef :
-                                     begin
-                                       { generate the high() value for the shortstring }
-                                       if (not iswrite) and
-                                          is_shortstring(tcallparanode(hp).left.resulttype.def) then
-                                         tcallparanode(hp).gen_high_tree(true);
-                                     end;
-                                   pointerdef :
-                                     begin
-                                       if not is_pchar(tcallparanode(hp).left.resulttype.def) then
-                                         CGMessage(type_e_cant_read_write_type);
-                                     end;
-                                   floatdef :
-                                     begin
-                                       isreal:=true;
-                                     end;
-                                   orddef :
-                                     begin
-                                       case torddef(tcallparanode(hp).left.resulttype.def).typ of
-                                         uchar,uwidechar,
-                                         u32bit,s32bit,
-                                         u64bit,s64bit:
-                                           ;
-                                         u8bit,s8bit,
-                                         u16bit,s16bit :
-                                           if iswrite then
-                                             inserttypeconv(tcallparanode(hp).left,s32bittype);
-                                         bool8bit,
-                                         bool16bit,
-                                         bool32bit :
-                                           if iswrite then
-                                             inserttypeconv(tcallparanode(hp).left,booltype)
-                                           else
-                                             CGMessage(type_e_cant_read_write_type);
-                                         else
-                                           CGMessage(type_e_cant_read_write_type);
-                                       end;
-                                     end;
-                                   arraydef :
-                                     begin
-                                       if is_chararray(tcallparanode(hp).left.resulttype.def) then
-                                         tcallparanode(hp).gen_high_tree(true)
-                                       else
-                                         CGMessage(type_e_cant_read_write_type);
-                                     end;
-                                   else
-                                     CGMessage(type_e_cant_read_write_type);
-                                 end;
-
-                                 { some format options ? }
-                                 if cpf_is_colon_para in tcallparanode(hp).callparaflags then
-                                   begin
-                                      if cpf_is_colon_para in tcallparanode(tcallparanode(hp).right).callparaflags then
-                                        begin
-                                           frac_para:=hp;
-                                           length_para:=tcallparanode(hp).right;
-                                           hp:=tcallparanode(hp).right;
-                                           hpp:=tcallparanode(hp).right;
-                                        end
-                                      else
-                                        begin
-                                           length_para:=hp;
-                                           frac_para:=nil;
-                                           hpp:=tcallparanode(hp).right;
-                                        end;
-                                      { can be nil if you use "write(e:0:6)" while e is undeclared (JM) }
-                                      if assigned(tcallparanode(hpp).left.resulttype.def) then
-                                        isreal:=(tcallparanode(hpp).left.resulttype.def.deftype=floatdef)
-                                      else
-                                        exit;
-                                      if (not is_integer(tcallparanode(length_para).left.resulttype.def)) then
-                                       CGMessage1(type_e_integer_expr_expected,tcallparanode(length_para).left.resulttype.def.typename)
-                                     else
-                                       inserttypeconv(tcallparanode(length_para).left,s32bittype);
-                                     if assigned(frac_para) then
-                                       begin
-                                         if isreal then
-                                          begin
-                                            if (not is_integer(tcallparanode(frac_para).left.resulttype.def)) then
-                                              CGMessage1(type_e_integer_expr_expected,tcallparanode(frac_para).left.resulttype.def.typename)
-                                            else
-                                              inserttypeconv(tcallparanode(frac_para).left,s32bittype);
-                                          end
-                                         else
-                                          CGMessage(parser_e_illegal_colon_qualifier);
-                                       end;
-                                     { do the checking for the colon'd arg }
-                                     hp:=length_para;
-                                   end;
-                               end;
-                              hp:=tcallparanode(hp).right;
-                           end;
-                      end;
-                    if codegenerror then
-                      exit;
-                    set_varstate(left,true);
-                 end;
-{$endif hascompilerproc}
                 end;
               in_settextbuf_file_x :
                 begin
@@ -1839,159 +1658,17 @@ implementation
               in_reset_typedfile,
               in_rewrite_typedfile :
                 begin
-{$ifdef hascompilerproc}
                   result := handle_reset_rewrite_typed;
-{$else hascompilerproc}
-                  set_varstate(left,true);
-                  resulttype:=voidtype;
-{$endif hascompilerproc}
                 end;
 
               in_str_x_string :
                 begin
-{$ifdef hascompilerproc}
                   result := handle_str;
-{$else hascompilerproc}
-                  resulttype:=voidtype;
-                  set_varstate(left,false);
-              { remove warning when result is passed }
-              set_funcret_is_valid(tcallparanode(left).left);
-              set_varstate(tcallparanode(tcallparanode(left).right).left,true);
-              hp:=left;
-              { valid string ? }
-              if not assigned(hp) or
-                 (tcallparanode(hp).left.resulttype.def.deftype<>stringdef) or
-                 (tcallparanode(hp).right=nil) then
-                CGMessage(cg_e_illegal_expression);
-              { we need a var parameter }
-              valid_for_var(tcallparanode(hp).left);
-              { with compilerproc's, this is not necessary anymore, the callnode }
-              { will convert it to an openstring itself if necessary (JM)        }
-              { generate the high() value for the shortstring }
-              if is_shortstring(tcallparanode(hp).left.resulttype.def) then
-                tcallparanode(hp).gen_high_tree(true);
-              { !!!! check length of string }
-              while assigned(tcallparanode(hp).right) do
-                hp:=tcallparanode(hp).right;
-              if not assigned(tcallparanode(hp).resulttype.def) then
-                exit;
-              { check and convert the first param }
-              if (cpf_is_colon_para in tcallparanode(hp).callparaflags) or
-                 not assigned(hp.resulttype.def) then
-                CGMessage(cg_e_illegal_expression);
-
-              isreal:=false;
-              case hp.resulttype.def.deftype of
-                orddef :
-                  begin
-                    case torddef(tcallparanode(hp).left.resulttype.def).typ of
-                      u32bit,s32bit,
-                      s64bit,u64bit:
-                        ;
-                      u8bit,s8bit,
-                      u16bit,s16bit:
-                        inserttypeconv(tcallparanode(hp).left,s32bittype);
-                      else
-                        CGMessage(type_e_integer_or_real_expr_expected);
-                    end;
-                  end;
-                floatdef :
-                  begin
-                    isreal:=true;
-                  end;
-                else
-                  CGMessage(type_e_integer_or_real_expr_expected);
-              end;
-
-              { some format options ? }
-              hpp:=tcallparanode(left).right;
-              if assigned(hpp) and (cpf_is_colon_para in tcallparanode(hpp).callparaflags) then
-                begin
-                  set_varstate(tcallparanode(hpp).left,true);
-                  if (not is_integer(tcallparanode(hpp).left.resulttype.def)) then
-                    CGMessage1(type_e_integer_expr_expected,tcallparanode(hpp).left.resulttype.def.typename)
-                  else
-                    inserttypeconv(tcallparanode(hpp).left,s32bittype);
-                  hpp:=tcallparanode(hpp).right;
-                  if assigned(hpp) and (cpf_is_colon_para in tcallparanode(hpp).callparaflags) then
-                    begin
-                      if isreal then
-                       begin
-                         if (not is_integer(tcallparanode(hpp).left.resulttype.def)) then
-                           CGMessage1(type_e_integer_expr_expected,tcallparanode(hpp).left.resulttype.def.typename)
-                         else
-                           begin
-                             set_varstate(tcallparanode(hpp).left,true);
-                             inserttypeconv(tcallparanode(hpp).left,s32bittype);
-                           end;
-                       end
-                      else
-                       CGMessage(parser_e_illegal_colon_qualifier);
-                    end;
-                end;
-{$endif hascompilerproc}
                 end;
 
               in_val_x :
                 begin
-{$ifdef hascompilerproc}
                   result := handle_val;
-{$else hascompilerproc}
-                  resulttype:=voidtype;
-              { check the amount of parameters }
-              if not(assigned(left)) or
-                 not(assigned(tcallparanode(left).right)) then
-               begin
-                 CGMessage(parser_e_wrong_parameter_size);
-                 exit;
-               end;
-              { there is a "code" parameter }
-              If Assigned(tcallparanode(tcallparanode(left).right).right) Then
-                Begin
-                   { first pass just the code parameter for first local use}
-                   hp := tcallparanode(left).right;
-                   tcallparanode(left).right := nil;
-                   make_not_regable(tcallparanode(left).left);
-                   set_varstate(left,false);
-                   if codegenerror then
-                    exit;
-                   tcallparanode(left).right := hp;
-                   { code has to be a var parameter }
-                   if valid_for_var(tcallparanode(left).left) then
-                    begin
-                      if (tcallparanode(left).left.resulttype.def.deftype <> orddef) or
-                         not(torddef(tcallparanode(left).left.resulttype.def).typ in [u16bit,s16bit,u32bit,s32bit]) then
-                       CGMessage(type_e_mismatch);
-                    end;
-                   hpp := tcallparanode(left).right
-                End
-              Else
-                hpp := left;
-              { now hpp = the destination value tree }
-              { first pass just the destination parameter for first local use }
-              hp:=tcallparanode(hpp).right;
-              tcallparanode(hpp).right:=nil;
-              { hpp = destination }
-              make_not_regable(tcallparanode(hpp).left);
-              set_varstate(hpp,false);
-              if codegenerror then
-                exit;
-              { remove warning when result is passed }
-              set_funcret_is_valid(tcallparanode(hpp).left);
-              tcallparanode(hpp).right := hp;
-              if valid_for_var(tcallparanode(hpp).left) then
-               begin
-                 If Not((tcallparanode(hpp).left.resulttype.def.deftype = floatdef) or
-                        is_integer(tcallparanode(hpp).left.resulttype.def)) then
-                   CGMessage(type_e_mismatch);
-               end;
-              { hp = source (String) }
-              { if not a stringdef then insert a type conv which
-                does the other type checking }
-              If (tcallparanode(hp).left.resulttype.def.deftype<>stringdef) then
-               inserttypeconv(tcallparanode(hp).left,cshortstringtype);
-              set_varstate(hp,true);
-{$endif hascompilerproc}
                 end;
 
               in_include_x_y,
@@ -2067,10 +1744,6 @@ implementation
                            else
                             if is_dynamic_array(left.resulttype.def) then
                               begin
-{$ifndef hascompilerproc}
-                                writeln('Error: high(dynamic_array) isn''t implemented yet');
-                                codegenerror := true;
-{$else hascompilerproc}
                                 { can't use inserttypeconv because we need }
                                 { an explicit type conversion (JM)         }
                                 hp := ctypeconvnode.create(left,voidpointertype);
@@ -2082,7 +1755,6 @@ implementation
                                 left:=nil;
                                 resulttypepass(hp);
                                 result:=hp;
-{$endif hascompilerproc}
                               end
                            else
                             begin
@@ -2469,62 +2141,8 @@ implementation
           in_write_x,
           in_writeln_x :
             begin
-{$ifdef hascompilerproc}
                { should be handled by det_resulttype }
                internalerror(200108234);
-{$else hascompilerproc}
-               { needs a call }
-               procinfo^.flags:=procinfo^.flags or pi_do_call;
-               { true, if readln needs an extra register }
-               extra_register:=false;
-               { we must know if it is a typed file or not }
-               { but we must first do the firstpass for it }
-               file_is_typed:=false;
-               if assigned(left) then
-                 begin
-                    iswrite:=(inlinenumber in [in_write_x,in_writeln_x]);
-                    { now we can check }
-                    hp:=left;
-                    while assigned(tcallparanode(hp).right) do
-                      hp:=tcallparanode(hp).right;
-                    { if resulttype.def is not assigned, then automatically }
-                    { file is not typed.                             }
-                    if assigned(hp) then
-                      Begin
-                        if (hp.resulttype.def.deftype=filedef) and
-                           (tfiledef(hp.resulttype.def).filetyp=ft_typed) then
-                          file_is_typed:=true;
-                      end; { endif assigned(hp) }
-                    if (not file_is_typed) then
-                      begin
-                         hp:=left;
-                         while assigned(hp) do
-                           begin
-{$ifdef i386}
-                             incrementregisterpushed($ff);
-{$else}
-                             incrementregisterpushed(ALL_REGISTERS);
-{$endif}
-                             if assigned(tcallparanode(hp).left.resulttype.def) then
-                               begin
-                                 case tcallparanode(hp).left.resulttype.def.deftype of
-                                   orddef :
-                                     begin
-                                       if not(iswrite) and
-                                          not(is_64bitint(tcallparanode(hp).left.resulttype.def)) then
-                                         extra_register:=true;
-                                     end;
-                                 end;
-                               end;
-                              hp:=tcallparanode(hp).right;
-                           end;
-                      end;
-                    { calc registers }
-                    left_max;
-                    if extra_register then
-                      inc(registers32);
-                 end;
-{$endif hascompilerproc}
             end;
          in_settextbuf_file_x :
            internalerror(200104262);
@@ -2532,48 +2150,20 @@ implementation
          in_reset_typedfile,
          in_rewrite_typedfile :
            begin
-{$ifndef hascompilerproc}
-              procinfo^.flags:=procinfo^.flags or pi_do_call;
-{$else not hascompilerproc}
               { should already be removed in det_resulttype (JM) }
               internalerror(200108236);
-{$endif not hascompilerproc}
            end;
 
          in_str_x_string :
            begin
-{$ifndef hascompilerproc}
-              procinfo^.flags:=procinfo^.flags or pi_do_call;
-              { calc registers }
-              left_max;
-{$else not hascompilerproc}
               { should already be removed in det_resulttype (JM) }
               internalerror(200108235);
-{$endif not hascompilerproc}
            end;
 
          in_val_x :
            begin
-{$ifdef hascompilerproc}
               { should already be removed in det_resulttype (JM) }
               internalerror(200108242);
-{$else hascompilerproc}
-              procinfo^.flags:=procinfo^.flags or pi_do_call;
-              { calc registers }
-              left_max;
-              { val doesn't calculate the registers really }
-              { correct, we need one register extra   (FK) }
-              { there is a "code" parameter }
-              If Assigned(tcallparanode(tcallparanode(left).right).right) Then
-                hpp := tcallparanode(left).right
-              Else
-                hpp := left;
-              { now hpp = the destination value tree }
-              if is_64bitint(tcallparanode(hpp).left.resulttype.def) then
-                inc(registers32,2)
-              else
-                inc(registers32,1);
-{$endif hascompilerproc}
            end;
 
          in_include_x_y,
@@ -2713,7 +2303,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.53  2001-08-27 11:04:41  jonas
+  Revision 1.54  2001-08-28 13:24:46  jonas
+    + compilerproc implementation of most string-related type conversions
+    - removed all code from the compiler which has been replaced by
+      compilerproc implementations (using {$ifdef hascompilerproc} is not
+      necessary in the compiler)
+
+  Revision 1.53  2001/08/27 11:04:41  jonas
     * avoid nonsense range error when using cardinal with value
       > high(longint) as code para with val()
 

+ 52 - 11
rtl/i386/i386.inc

@@ -706,10 +706,46 @@ end;
 ****************************************************************************}
 
 {$define FPC_SYSTEM_HAS_FPC_SHORTSTR_COPY}
-procedure fpc_shortstr_copy(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_COPY']; {$ifdef hascompilerproc} compilerproc; {$endif}
-{
-  this procedure must save all modified registers except EDI and ESI !!!
-}
+
+function fpc_shortstr_to_shortstr(len:longint; const sstr: shortstring): shortstring; [public,alias: 'FPC_SHORTSTR_TO_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
+begin
+  asm
+        cld
+        movl    __RESULT,%edi
+        movl    sstr,%esi
+        xorl    %eax,%eax
+        movl    len,%ecx
+        lodsb
+        cmpl    %ecx,%eax
+        jbe     .LStrCopy1
+        movl    %ecx,%eax
+.LStrCopy1:
+        stosb
+        cmpl    $7,%eax
+        jl      .LStrCopy2
+        movl    %edi,%ecx       { Align on 32bits }
+        negl    %ecx
+        andl    $3,%ecx
+        subl    %ecx,%eax
+        rep
+        movsb
+        movl    %eax,%ecx
+        andl    $3,%eax
+        shrl    $2,%ecx
+        rep
+        movsl
+.LStrCopy2:
+        movl    %eax,%ecx
+        rep
+        movsb
+  end ['ESI','EDI','EAX','ECX'];
+end;
+
+{$ifdef had_openstrings}
+{$p+}
+{$endif had_openstrings}
+
+procedure fpc_shortstr_copy(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_COPY'];
 begin
   asm
         pushl   %eax
@@ -747,9 +783,8 @@ begin
   end ['ESI','EDI'];
 end;
 
-
 {$define FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
-procedure fpc_shortstr_concat(s1,s2:pointer);
+procedure fpc_shortstr_concat(const s1,s2:shortstring);
   [public,alias:'FPC_SHORTSTR_CONCAT']; {$ifdef hascompilerproc} compilerproc; {$endif}
 begin
   asm
@@ -789,7 +824,7 @@ end;
 
 
 {$define FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
-function fpc_shortstr_compare(dstr,sstr:pointer): longint; [public,alias:'FPC_SHORTSTR_COMPARE']; {$ifdef hascompilerproc} compilerproc; {$endif}
+function fpc_shortstr_compare(const dstr,sstr:shortstring): longint; [public,alias:'FPC_SHORTSTR_COMPARE']; {$ifdef hascompilerproc} compilerproc; {$endif}
 begin
   asm
         cld
@@ -847,12 +882,12 @@ function strlen(p:pchar):longint;assembler;
 {$include strlen.inc}
 
 {$define FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
-function fpc_chararray_to_shortstr(p:pchar; l : longint):shortstring;[public,alias:'FPC_CHARARRAY_TO_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
+function fpc_chararray_to_shortstr(const arr: array of char):shortstring;[public,alias:'FPC_CHARARRAY_TO_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
 begin
   asm
         cld
-        movl    p,%esi
-        movl    l,%ecx
+        movl    arr,%esi
+        movl    arr+4,%ecx
         orl     %esi,%esi
         jnz     .LStrCharArrayNotNil
         movl    $0,%ecx
@@ -1104,7 +1139,13 @@ procedure inclocked(var l : longint);assembler;
 
 {
   $Log$
-  Revision 1.14  2001-08-01 15:00:09  jonas
+  Revision 1.15  2001-08-28 13:24:47  jonas
+    + compilerproc implementation of most string-related type conversions
+    - removed all code from the compiler which has been replaced by
+      compilerproc implementations (using {$ifdef hascompilerproc} is not
+      necessary in the compiler)
+
+  Revision 1.14  2001/08/01 15:00:09  jonas
     + "compproc" helpers
     * renamed several helpers so that their name is the same as their
       "public alias", which should facilitate the conversion of processor

+ 78 - 45
rtl/inc/astrings.inc

@@ -217,27 +217,31 @@ end;
 {$endif EXTRAANSISHORT}
 
 
-Procedure fpc_AnsiStr_To_ShortStr (Var S1 : ShortString;S2 : Pointer);[Public, alias: 'FPC_ANSISTR_TO_SHORTSTR'];  {$ifdef hascompilerproc} compilerproc; {$endif}
+{ the following declaration has exactly the same effect as                   }
+{ procedure fpc_AnsiStr_To_ShortStr (Var S1 : ShortString;S2 : Pointer);     }
+{ which is what the old helper was, so we don't need an extra implementation }
+{ of the old helper (JM)                                                     }
+function fpc_AnsiStr_To_ShortStr (high_of_res: longint;const S2 : Ansistring): shortstring;[Public, alias: 'FPC_ANSISTR_TO_SHORTSTR'];  {$ifdef hascompilerproc} compilerproc; {$endif}
 {
   Converts a AnsiString to a ShortString;
 }
 Var
   Size : Longint;
 begin
-  if S2=nil then
-   S1:=''
+  if S2='' then
+   fpc_AnsiStr_To_ShortStr:=''
   else
    begin
-     Size:=PAnsiRec(S2-FirstOff)^.Len;
-     If Size>high(S1) then
-      Size:=high(S1);
-     Move (S2^,S1[1],Size);
-     byte(S1[0]):=Size;
+     Size:=Length(S2);
+     If Size>high_of_res then
+      Size:=high_of_res;
+     Move (S2[1],fpc_AnsiStr_To_ShortStr[1],Size);
+     byte(fpc_AnsiStr_To_ShortStr[0]):=Size;
    end;
 end;
 
 
-Procedure fpc_ShortStr_To_AnsiStr (Var S1 : Pointer; Const S2 : ShortString);[Public, alias: 'FPC_SHORTSTR_TO_ANSISTR'];  {$ifdef hascompilerproc} compilerproc; {$endif}
+Function fpc_ShortStr_To_AnsiStr (Const S2 : ShortString): ansistring; {$ifdef hascompilerproc} compilerproc; {$endif}
 {
   Converts a ShortString to a AnsiString;
 }
@@ -245,63 +249,86 @@ Var
   Size : Longint;
 begin
   Size:=Length(S2);
-  Setlength (AnsiString(S1),Size);
+  Setlength (fpc_ShortStr_To_AnsiStr,Size);
   if Size>0 then
-   begin
-     Move (S2[1],Pointer(S1)^,Size);
-     { Terminating Zero }
-     PByte(Pointer(S1)+Size)^:=0;
-   end;
+    Move(S2[1],Pointer(fpc_ShortStr_To_AnsiStr)^,Size);
 end;
 
+{ old style helper }
+{$ifndef hascompilerproc}
+Procedure fpc_ShortStr_To_AnsiStr (Var S1 : Pointer; Const S2 : ShortString);[Public, alias: 'FPC_SHORTSTR_TO_ANSISTR'];
+begin
+  s1 := pointer(fpc_ShortStr_To_AnsiStr(s2));
+end;
+{$endif hascompilerproc}
 
-Procedure fpc_Char_To_AnsiStr(var S1 : Pointer; c : Char);[Public, alias: 'FPC_CHAR_TO_ANSISTR'];  {$ifdef hascompilerproc} compilerproc; {$endif}
+Function fpc_Char_To_AnsiStr(const c : Char): AnsiString; {$ifdef hascompilerproc} compilerproc; {$endif}
 {
-  Converts a ShortString to a AnsiString;
+  Converts a Char to a AnsiString;
 }
 begin
-  Setlength (AnsiString(S1),1);
-  PByte(Pointer(S1))^:=byte(c);
+  if c = #0 then
+    { result is automatically set to '' }
+    exit;
+  Setlength (fpc_Char_To_AnsiStr,1);
+  PByte(Pointer(fpc_Char_To_AnsiStr))^:=byte(c);
   { Terminating Zero }
-  PByte(Pointer(S1)+1)^:=0;
+  PByte(Pointer(fpc_Char_To_AnsiStr)+1)^:=0;
+end;
+
+{ old style helper }
+{$ifndef hascompilerproc}
+Procedure fpc_Char_To_AnsiStr(var S1 : Pointer; c : Char);[Public, alias: 'FPC_CHAR_TO_ANSISTR'];
+begin
+  s1 := pointer(fpc_Char_To_AnsiStr(c));
 end;
+{$endif hascompilerproc}
 
 
-Procedure fpc_PChar_To_AnsiStr(var a : ansistring;p : pchar);[Public,Alias : 'FPC_PCHAR_TO_ANSISTR'];  {$ifdef hascompilerproc} compilerproc; {$endif}
+Function fpc_PChar_To_AnsiStr(const p : pchar): ansistring; {$ifdef hascompilerproc} compilerproc; {$endif}
 Var
   L : Longint;
 begin
-  if pointer(a)<>nil then
-    begin
-       fpc_AnsiStr_Decr_Ref(Pointer(a));
-       pointer(a):=nil;
-    end;
   if (not assigned(p)) or (p[0]=#0) Then
-    Pointer(a):=nil
-  else
-    begin
-      l:=IndexChar(p^,-1,#0);
-      Pointer(a):=NewAnsistring(L);
-      SetLength(A,L);
-      Move (P[0],Pointer(A)^,L)
-    end;
+    { result is automatically set to '' }
+    exit;
+  l:=IndexChar(p^,-1,#0);
+  SetLength(fpc_PChar_To_AnsiStr,L);
+  Move (P[0],Pointer(fpc_PChar_To_AnsiStr)^,L)
+end;
+
+{ old style helper }
+{$ifndef hascompilerproc}
+Procedure fpc_PChar_To_AnsiStr(var a : ansistring;p : pchar);[Public,Alias : 'FPC_PCHAR_TO_ANSISTR'];  {$ifdef hascompilerproc} compilerproc; {$endif}
+begin
+  pointer(a) := pointer(fpc_PChar_To_AnsiStr(p));
 end;
+{$endif hascompilerproc}
 
 
-Procedure fpc_CharArray_To_AnsiStr(var a : ansistring;p : pchar;l:longint);[Public,Alias : 'FPC_CHARARRAY_TO_ANSISTR'];  {$ifdef hascompilerproc} compilerproc; {$endif}
+Function fpc_CharArray_To_AnsiStr(const arr: array of char): ansistring; {$ifdef hascompilerproc} compilerproc; {$endif}
 var
   i  : longint;
 begin
-  if p[0]=#0 Then
-    Pointer(a):=nil
-  else
-    begin
-      i:=IndexChar(p^,L,#0);
-      Pointer(a):=NewAnsistring(i);
-      SetLength(a,i);
-      Move (P[0],Pointer(A)^,i);
-    end;
+  if arr[0]=#0 Then
+    { result is automatically set to '' }
+    exit;
+  i:=IndexChar(arr,high(arr)+1,#0);
+  SetLength(fpc_CharArray_To_AnsiStr,i);
+  Move (arr[0],Pointer(fpc_CharArray_To_AnsiStr)^,i);
+end;
+
+{ old style helper }
+{$ifndef hascompilerproc}
+{ the declaration below is the same as                                              }
+{ Procedure fpc_CharArray_To_AnsiStr(var a : ansistring; p: pointer; len: longint); }
+{ which is what the old helper was (we need the parameter as "array of char" type   }
+{ so we can pass it to the new style helper (JM)                                    }
+Procedure fpc_CharArray_To_AnsiStr(var a : ansistring; const arr: array of char);[Public,Alias : 'FPC_CHARARRAY_TO_ANSISTR'];  {$ifdef hascompilerproc} compilerproc; {$endif}
+begin
+  pointer(a) := pointer(fpc_CharArray_To_AnsiStr(arr));
 end;
+{$endif hascompilerproc}
 
 
 Function fpc_AnsiStr_Compare(S1,S2 : Pointer): Longint;[Public,Alias : 'FPC_ANSISTR_COMPARE'];  {$ifdef hascompilerproc} compilerproc; {$endif}
@@ -732,7 +759,13 @@ end;
 
 {
   $Log$
-  Revision 1.18  2001-08-13 12:40:16  jonas
+  Revision 1.19  2001-08-28 13:24:47  jonas
+    + compilerproc implementation of most string-related type conversions
+    - removed all code from the compiler which has been replaced by
+      compilerproc implementations (using {$ifdef hascompilerproc} is not
+      necessary in the compiler)
+
+  Revision 1.18  2001/08/13 12:40:16  jonas
     * renamed some str(x,y) and val(x,y) helpers so the naming scheme is the
       same for all string types
     + added the str(x,y) and val(x,y,z) helpers for int64/qword to

+ 24 - 17
rtl/inc/compproc.inc

@@ -25,11 +25,12 @@
 {$ifdef hascompilerproc}
 
 procedure fpc_Shortstr_SetLength(var s:shortstring;len:StrLenInt); compilerproc;
-procedure fpc_shortstr_copy(len:longint;sstr,dstr:pointer); compilerproc;
-procedure fpc_shortstr_concat(s1,s2:pointer); compilerproc;
-function fpc_shortstr_compare(dstr,sstr:pointer) : longint; compilerproc;
+function fpc_shortstr_to_shortstr(len:longint; const sstr: shortstring): shortstring; compilerproc;
+procedure fpc_shortstr_concat(const s1,s2:shortstring); compilerproc;
+function fpc_shortstr_compare(const dstr,sstr:shortstring) : longint; compilerproc;
+function fpc_pchar_to_shortstr(p:pchar):shortstring; compilerproc;
 
-function fpc_chararray_to_shortstr(p:pchar; l : longint):shortstring; compilerproc;
+function fpc_chararray_to_shortstr(const arr: array of char):shortstring; compilerproc;
 procedure fpc_str_to_chararray(strtyp, arraysize: longint; src,dest: pchar);compilerproc;
 
 function fpc_dynarray_length(p : pointer) : tdynarrayindex; compilerproc;
@@ -55,11 +56,11 @@ Procedure fpc_AnsiStr_Concat (S1,S2 : Pointer;var S3 : Pointer); compilerproc;
 {$ifdef EXTRAANSISHORT}
 Procedure fpc_AnsiStr_ShortStr_Concat (Var S1: AnsiString; Var S2 : ShortString); compilerproc;
 {$endif EXTRAANSISHORT}
-Procedure fpc_AnsiStr_To_ShortStr (Var S1 : ShortString;S2 : Pointer); compilerproc;
-Procedure fpc_ShortStr_To_AnsiStr (Var S1 : Pointer; Const S2 : ShortString); compilerproc;
-Procedure fpc_Char_To_AnsiStr(var S1 : Pointer; c : Char); compilerproc;
-Procedure fpc_PChar_To_AnsiStr(var a : ansistring;p : pchar); compilerproc;
-Procedure fpc_CharArray_To_AnsiStr(var a : ansistring;p : pchar;l:longint); compilerproc;
+function fpc_AnsiStr_To_ShortStr (high_of_res: longint;const S2 : Ansistring): shortstring; compilerproc;
+Function fpc_ShortStr_To_AnsiStr (Const S2 : ShortString): ansistring; compilerproc;
+Function fpc_Char_To_AnsiStr(const c : Char): AnsiString; compilerproc;
+Function fpc_PChar_To_AnsiStr(const p : pchar): ansistring; compilerproc;
+Function fpc_CharArray_To_AnsiStr(const arr: array of char): ansistring; compilerproc;
 Function fpc_AnsiStr_Compare(S1,S2 : Pointer): Longint; compilerproc;
 Procedure fpc_AnsiStr_CheckZero(p : pointer); compilerproc;
 Procedure fpc_AnsiStr_CheckRange(len,index : longint); compilerproc;
@@ -71,15 +72,15 @@ Procedure fpc_ansistr_Unique(Var S : AnsiString); compilerproc;
 
 Procedure fpc_WideStr_Decr_Ref (Var S : Pointer); compilerproc;
 Procedure fpc_WideStr_Incr_Ref (Var S : Pointer); compilerproc;
-Procedure fpc_WideStr_To_ShortStr (Var S1 : ShortString;S2 : Pointer); compilerproc;
-Procedure fpc_ShortStr_To_WideStr (Var S1 : Pointer; Const S2 : ShortString); compilerproc;
-Procedure fpc_WideStr_To_AnsiStr (Var S1 : Pointer;S2 : Pointer); compilerproc;
-Procedure fpc_AnsiStr_To_WideStr (Var S1 : Pointer; Const S2 : Pointer); compilerproc;
+function fpc_WideStr_To_ShortStr (high_of_res: longint;const S2 : WideString): shortstring; compilerproc;
+Function fpc_ShortStr_To_WideStr (Const S2 : ShortString): WideString; compilerproc;
+Function fpc_WideStr_To_AnsiStr (const S2 : WideString): AnsiString; compilerproc;
+Function fpc_AnsiStr_To_WideStr (Const S2 : AnsiString): WideString; compilerproc;
 Procedure fpc_WideStr_Assign (Var S1 : Pointer;S2 : Pointer); compilerproc;
 Procedure fpc_WideStr_Concat (S1,S2 : Pointer;var S3 : Pointer); compilerproc;
-Procedure fpc_Char_To_WideStr(var S1 : Pointer; c : Char); compilerproc;
-Procedure fpc_PChar_To_WideStr(var a : widestring;p : pchar); compilerproc;
-Procedure fpc_CharArray_To_WideStr(var a : widestring;p : pchar;l:longint); compilerproc;
+Function fpc_Char_To_WideStr(const c : Char): WideString; compilerproc;
+Function fpc_PChar_To_WideStr(const p : pchar): WideString; compilerproc;
+Function fpc_CharArray_To_WideStr(const arr: array of char): WideString; compilerproc;
 Function fpc_WideStr_Compare(S1,S2 : Pointer): Longint; compilerproc;
 Procedure fpc_WideStr_CheckZero(p : pointer); compilerproc;
 Procedure fpc_WideStr_CheckRange(len,index : longint); compilerproc;
@@ -230,7 +231,13 @@ Procedure fpc_typed_read(TypeSize : Longint;var f : TypedFile;var Buf); compiler
 
 {
   $Log$
-  Revision 1.4  2001-08-23 14:28:36  jonas
+  Revision 1.5  2001-08-28 13:24:47  jonas
+    + compilerproc implementation of most string-related type conversions
+    - removed all code from the compiler which has been replaced by
+      compilerproc implementations (using {$ifdef hascompilerproc} is not
+      necessary in the compiler)
+
+  Revision 1.4  2001/08/23 14:28:36  jonas
     + tempcreate/ref/delete nodes (allows the use of temps in the
       resulttype and first pass)
     * made handling of read(ln)/write(ln) processor independent

+ 39 - 5
rtl/inc/generic.inc

@@ -482,12 +482,35 @@ end;
 
 {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COPY}
 
-procedure fpc_shortstr_copy(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_COPY']; {$ifdef hascompilerproc} compilerproc; {$endif}
+function fpc_shortstr_to_shortstr(len:longint;const sstr:shortstring): shortstring;[public,alias:'FPC_SHORTSTR_TO_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
+var
+  slen : byte;
+begin
+{ these are shortstrings, not pointers! (JM)
+  if dstr=nil then
+    exit;
+  if sstr=nil then
+    begin
+      if dstr<>nil then
+        pstring(dstr)^[0]:=#0;
+      exit;
+    end;
+}
+  slen:=length(pstring(sstr)^);
+  if slen<len then
+    len:=slen;
+  { don't forget the length character }
+  if len <> 0 then
+      move(sstr[0],result[0],len+1);
+end;
+
+procedure fpc_shortstr_copy(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_COPY'];
 var
   slen : byte;
 type
   pstring = ^string;
 begin
+{ these are shortstrings, not pointers! (JM)
   if dstr=nil then
     exit;
   if sstr=nil then
@@ -496,20 +519,25 @@ begin
         pstring(dstr)^[0]:=#0;
       exit;
     end;
+}
   slen:=length(pstring(sstr)^);
   if slen<len then
     len:=slen;
   { don't forget the length character }
   if len <> 0 then
       move(sstr^,dstr^,len+1);
+ { already done by the move above (JM)
   pstring(dstr)^[0]:=chr(len);
+ }
 end;
 
+
+
 {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COPY}
 
 {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
 
-procedure fpc_shortstr_concat(s1,s2:pointer);[public,alias:'FPC_SHORTSTR_CONCAT'];  {$ifdef hascompilerproc} compilerproc; {$endif}
+procedure fpc_shortstr_concat(const s1,s2:shortstring);[public,alias:'FPC_SHORTSTR_CONCAT'];  {$ifdef hascompilerproc} compilerproc; {$endif}
 var
   s1l, s2l : byte;
 type
@@ -529,7 +557,7 @@ end;
 
 {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
 
-function fpc_shortstr_compare(rightstr,leftstr:pointer) : longint;[public,alias:'FPC_SHORTSTR_COMPARE']; {$ifdef hascompilerproc} compilerproc; {$endif}
+function fpc_shortstr_compare(const rightstr,leftstr:shortstring) : longint;[public,alias:'FPC_SHORTSTR_COMPARE']; {$ifdef hascompilerproc} compilerproc; {$endif}
 var
    s1,s2,max,i : byte;
    d : longint;
@@ -627,7 +655,7 @@ begin
     { longstring }
     2:;
     { widestring }
-    3:;
+    3: ;
   end;
   if len > arraysize then
     len := arraysize;
@@ -829,7 +857,13 @@ end;
 
 {
   $Log$
-  Revision 1.17  2001-08-01 15:00:10  jonas
+  Revision 1.18  2001-08-28 13:24:47  jonas
+    + compilerproc implementation of most string-related type conversions
+    - removed all code from the compiler which has been replaced by
+      compilerproc implementations (using {$ifdef hascompilerproc} is not
+      necessary in the compiler)
+
+  Revision 1.17  2001/08/01 15:00:10  jonas
     + "compproc" helpers
     * renamed several helpers so that their name is the same as their
       "public alias", which should facilitate the conversion of processor

+ 122 - 75
rtl/inc/wstrings.inc

@@ -200,27 +200,27 @@ Begin
 end;
 
 
-Procedure fpc_WideStr_To_ShortStr (Var S1 : ShortString;S2 : Pointer);[Public, alias: 'FPC_WIDESTR_TO_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
+function fpc_WideStr_To_ShortStr (high_of_res: longint;const S2 : WideString): shortstring;[Public, alias: 'FPC_WIDESTR_TO_SHORTSTR'];  {$ifdef hascompilerproc} compilerproc; {$endif}
 {
   Converts a WideString to a ShortString;
 }
 Var
   Size : Longint;
 begin
-  if S2=nil then
-   S1:=''
+  if S2='' then
+   fpc_WideStr_To_ShortStr:=''
   else
    begin
-     Size:=PWideRec(S2-FirstOff)^.Len;
-     If Size>high(S1) then
-      Size:=high(S1);
-     Wide2AnsiMoveProc(PWideChar(S2),PChar(@S1[1]),Size);
-     byte(S1[0]):=Size;
+     Size:=Length(S2);
+     If Size>high_of_res then
+      Size:=high_of_res;
+     Wide2AnsiMoveProc(PWideChar(S2),PChar(@fpc_WideStr_To_ShortStr[1]),Size);
+     byte(fpc_WideStr_To_ShortStr[0]):=Size;
    end;
 end;
 
 
-Procedure fpc_ShortStr_To_WideStr (Var S1 : Pointer; Const S2 : ShortString);[Public, alias: 'FPC_SHORTSTR_TO_WIDESTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
+Function fpc_ShortStr_To_WideStr (Const S2 : ShortString): WideString; {$ifdef hascompilerproc} compilerproc; {$endif}
 {
   Converts a ShortString to a WideString;
 }
@@ -228,57 +228,79 @@ Var
   Size : Longint;
 begin
   Size:=Length(S2);
-  Setlength (WideString(S1),Size);
+  Setlength (fpc_ShortStr_To_WideStr,Size);
   if Size>0 then
-   Ansi2WideMoveProc(PChar(@S2[1]),PWideChar(S1),Size);
+    begin
+      Ansi2WideMoveProc(PChar(@S2[1]),PWideChar(Pointer(fpc_ShortStr_To_WideStr)),Size);
+      { Terminating Zero }
+      PWideChar(Pointer(fpc_ShortStr_To_WideStr)+Size*sizeof(WideChar))^:=#0;
+    end;
 end;
 
+{ old style helper }
+{$ifndef hascompilerproc}
 
-Procedure fpc_WideStr_To_AnsiStr (Var S1 : Pointer;S2 : Pointer);[Public, alias: 'FPC_WIDESTR_TO_ANSISTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
+Procedure fpc_ShortStr_To_WideStr (Var S1 : Pointer; Const S2 : ShortString);[Public, alias: 'FPC_SHORTSTR_TO_WIDESTR'];
+begin
+  s1 := pointer(fpc_ShortStr_To_WideStr(s2));
+end;
+{$endif hascompilerproc}
+
+Function fpc_WideStr_To_AnsiStr (const S2 : WideString): AnsiString; {$ifdef hascompilerproc} compilerproc; {$endif}
 {
   Converts a WideString to an AnsiString
 }
 Var
   Size : Longint;
 begin
-  if s2=nil then
-    s1:=nil
-  else
-    begin
-       Size:=Length(WideString(S2));
-       Setlength (AnsiString(S1),Size);
-       if Size>0 then
-        begin
-          Wide2AnsiMoveProc(PWideChar(S2),PChar(S1),Size);
-          { Terminating Zero }
-          PChar(S1+Size)^:=#0;
-        end;
-    end;
+  if s2='' then
+    exit;
+  Size:=Length(WideString(S2));
+  Setlength (fpc_WideStr_To_AnsiStr,Size);
+  if Size>0 then
+   begin
+     Wide2AnsiMoveProc(PWideChar(Pointer(S2)),PChar(Pointer(fpc_WideStr_To_AnsiStr)),Size);
+     { Terminating Zero }
+     PChar(Pointer(fpc_WideStr_To_AnsiStr)+Size)^:=#0;
+   end;
 end;
 
+{ old style helper }
+{$ifndef hascompilerproc}
+Procedure fpc_WideStr_To_AnsiStr (Var S1 : Pointer;const S2 : WideString);[Public, alias: 'FPC_WIDESTR_TO_ANSISTR'];
+begin
+  s1 := pointer(fpc_WideStr_To_AnsiStr(s2));
+end;
+{$endif hascompilerproc}
+
 
-Procedure fpc_AnsiStr_To_WideStr (Var S1 : Pointer; Const S2 : Pointer);[Public, alias: 'FPC_ANSISTR_TO_WIDESTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
+Function fpc_AnsiStr_To_WideStr (Const S2 : AnsiString): WideString; {$ifdef hascompilerproc} compilerproc; {$endif}
 {
   Converts an AnsiString to a WideString;
 }
 Var
   Size : Longint;
 begin
-   if s2=nil then
-     s1:=nil
-   else
-     begin
-       Size:=Length(AnsiString(S2));
-       Setlength (WideString(S1),Size);
-       if Size>0 then
-        begin
-          Ansi2WideMoveProc(PChar(S2),PWideChar(S1),Size);
-          { Terminating Zero }
-          PWideChar(S1+Size*sizeof(WideChar))^:=#0;
-        end;
-     end;
+   if s2='' then
+     exit;
+   Size:=Length(S2);
+   Setlength (fpc_AnsiStr_To_WideStr,Size);
+   if Size>0 then
+    begin
+      Ansi2WideMoveProc(PChar(S2),PWideChar(Pointer(fpc_AnsiStr_To_WideStr)),Size);
+      { Terminating Zero }
+      PWideChar(Pointer(fpc_AnsiStr_To_WideStr)+Size*sizeof(WideChar))^:=#0;
+    end;
 end;
 
+{ old style helper }
+{$ifndef hascompilerproc}
+Procedure fpc_AnsiStr_To_WideStr (Var S1 : Pointer; Const S2 : AnsiString);[Public, alias: 'FPC_ANSISTR_TO_WIDESTR'];
+begin
+  s1 := pointer(fpc_AnsiStr_To_WideStr(s2));
+end;
+{$endif hascompilerproc}
+
 
 { checked against the ansistring routine, 2001-05-27 (FK) }
 Procedure fpc_WideStr_Assign (Var S1 : Pointer;S2 : Pointer);[Public,Alias:'FPC_WIDESTR_ASSIGN']; {$ifdef hascompilerproc} compilerproc; {$endif}
@@ -328,54 +350,73 @@ begin
 end;
 
 
-Procedure fpc_Char_To_WideStr(var S1 : Pointer; c : Char);[Public, alias: 'FPC_CHAR_TO_WIDESTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
+Function fpc_Char_To_WideStr(const c : Char): WideString; {$ifdef hascompilerproc} compilerproc; {$endif}
 {
   Converts a Char to a WideString;
 }
 begin
-  Setlength (WideString(S1),1);
-  PWideChar(S1)^:=c;
+  if c = #0 then
+    { result is automatically set to '' }
+    exit;
+  Setlength (fpc_Char_To_WideStr,1);
+  fpc_Char_To_WideStr[1]:=c;
   { Terminating Zero }
-  PWideChar(S1+sizeof(WideChar))^:=#0;
+  PWideChar(Pointer(fpc_Char_To_WideStr)+sizeof(WideChar))^:=#0;
 end;
 
+{ old style helper }
+{$ifndef hascompilerproc}
+Procedure fpc_Char_To_WideStr(var S1 : Pointer; c : Char);[Public, alias: 'FPC_CHAR_TO_WIDESTR'];
+begin
+  s1 := pointer(fpc_Char_To_WideStr(c));
+end;
+{$endif hascompilerproc}
 
-Procedure fpc_PChar_To_WideStr(var a : widestring;p : pchar);[Public,Alias : 'FPC_PCHAR_TO_WIDESTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
+
+Function fpc_PChar_To_WideStr(const p : pchar): WideString; {$ifdef hascompilerproc} compilerproc; {$endif}
 Var
   L : Longint;
 begin
-  if pointer(a)<>nil then
-    begin
-       fpc_WideStr_Decr_Ref(Pointer(a));
-       pointer(a):=nil;
-    end;
   if (not assigned(p)) or (p[0]=#0) Then
-    Pointer(a):=nil
-  else
-    begin
-      l:=IndexChar(p^,-1,#0);
-      Pointer(a):=NewWidestring(L);
-      SetLength(A,L);
-      Ansi2WideMoveProc(P,PWideChar(A),L);
-    end;
+    { result is automatically set to '' }
+    exit;
+  l:=IndexChar(p^,-1,#0);
+  SetLength(fpc_PChar_To_WideStr,L);
+  Ansi2WideMoveProc(P,PWideChar(Pointer(fpc_PChar_To_WideStr)),l);
 end;
 
+{ old style helper }
+{$ifndef hascompilerproc}
 
-Procedure fpc_CharArray_To_WideStr(var a : widestring;p : pchar;l:longint);[Public,Alias : 'FPC_CHARARRAY_TO_WIDESTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
+Procedure fpc_PChar_To_WideStr(var a : WideString;p : pchar);[Public,Alias : 'FPC_PCHAR_TO_WIDESTR'];  {$ifdef hascompilerproc} compilerproc; {$endif}
+begin
+  pointer(a) := pointer(fpc_PChar_To_WideStr(p));
+end;
+{$endif hascompilerproc}
+
+Function fpc_CharArray_To_WideStr(const arr: array of char): WideString; {$ifdef hascompilerproc} compilerproc; {$endif}
 var
   i  : longint;
 begin
-  if p[0]=#0 Then
-    Pointer(a):=nil
-  else
-    begin
-      i:=IndexChar(p^,L,#0);
-      Pointer(a):=NewWidestring(i);
-      SetLength(a,i);
-      Ansi2WideMoveProc(P,PWideChar(A),i);
-    end;
+  if arr[0]=#0 Then
+    { result is automatically set to '' }
+    exit;
+  i:=IndexChar(arr,high(arr)+1,#0);
+  SetLength(fpc_CharArray_To_WideStr,i);
+  Ansi2WideMoveProc (pchar(@arr),PWideChar(Pointer(fpc_CharArray_To_WideStr)),i);
 end;
 
+{ old style helper }
+{$ifndef hascompilerproc}
+{ the declaration below is the same as                                              }
+{ Procedure fpc_CharArray_To_WideStr(var a : WideString; p: pointer; len: longint); }
+{ which is what the old helper was (we need the parameter as "array of char" type   }
+{ so we can pass it to the new style helper (JM)                                    }
+Procedure fpc_CharArray_To_WideStr(var a : WideString; const arr: array of char);[Public,Alias : 'FPC_CHARARRAY_TO_WIDESTR'];  {$ifdef hascompilerproc} compilerproc; {$endif}
+begin
+  pointer(a) := pointer(fpc_CharArray_To_WideStr(arr));
+end;
+{$endif hascompilerproc}
 
 Function fpc_WideStr_Compare(S1,S2 : Pointer): Longint;[Public,Alias : 'FPC_WIDESTR_COMPARE']; {$ifdef hascompilerproc} compilerproc; {$endif}
 {
@@ -668,7 +709,7 @@ end;}
 
 Function fpc_Val_Real_WideStr(Const S : WideString; Var Code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_WIDESTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
 Var
-  SS : String; 
+  SS : String;
 begin
   fpc_Val_Real_WideStr := 0;
   if length(S) > 255 then
@@ -693,11 +734,11 @@ begin
       SS := S;
       Val(SS,fpc_Val_UInt_WideStr,code);
     end;
-end; 
+end;
 
 
 Function fpc_Val_SInt_WideStr (DestSize: longint; Const S : WideString; Var Code : ValSInt): ValSInt; [public, alias:'FPC_VAL_SINT_WIDESTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
-Var   
+Var
   SS : ShortString;
 begin
   fpc_Val_SInt_WideStr:=0;
@@ -708,7 +749,7 @@ begin
       SS := S;
       fpc_Val_SInt_WideStr := fpc_Val_SInt_ShortStr(DestSize,SS,Code);
     end;
-end; 
+end;
 
 Function fpc_Val_qword_WideStr (Const S : WideString; Var Code : ValSInt): qword; [public, alias:'FPC_VAL_QWORD_WIDESTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
 Var
@@ -722,9 +763,9 @@ begin
        SS := S;
        Val(SS,fpc_Val_qword_WideStr,Code);
     end;
-end; 
-  
-  
+end;
+
+
 Function fpc_Val_int64_WideStr (Const S : WideString; Var Code : ValSInt): Int64; [public, alias:'FPC_VAL_INT64_WIDESTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
 Var
   SS : ShortString;
@@ -771,7 +812,13 @@ end;
 
 {
   $Log$
-  Revision 1.12  2001-08-13 12:40:16  jonas
+  Revision 1.13  2001-08-28 13:24:47  jonas
+    + compilerproc implementation of most string-related type conversions
+    - removed all code from the compiler which has been replaced by
+      compilerproc implementations (using {$ifdef hascompilerproc} is not
+      necessary in the compiler)
+
+  Revision 1.12  2001/08/13 12:40:16  jonas
     * renamed some str(x,y) and val(x,y) helpers so the naming scheme is the
       same for all string types
     + added the str(x,y) and val(x,y,z) helpers for int64/qword to