Browse Source

+ 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 năm trước cách đây
mục cha
commit
fc92c3b336
10 tập tin đã thay đổi với 432 bổ sung1803 xóa
  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