Browse Source

* fixed ansistring -> pchar type conversion on JVM target now that empty
ansistrings are represented by nil
* fixed type conversion of constant empty ansistring/unicodestring to
pchar/pwidechar on the JVM target

git-svn-id: branches/jvmbackend@21055 -

Jonas Maebe 13 năm trước cách đây
mục cha
commit
0659058e44
4 tập tin đã thay đổi với 40 bổ sung10 xóa
  1. 25 7
      compiler/jvm/njvmcnv.pas
  2. 1 1
      rtl/java/jastringh.inc
  3. 11 0
      rtl/java/jastrings.inc
  4. 3 2
      rtl/java/jsystem.inc

+ 25 - 7
compiler/jvm/njvmcnv.pas

@@ -483,15 +483,16 @@ implementation
             result:=nil;
             exit;
           end;
-        result:=ctypeconvnode.create_explicit(left,java_ansistring);
         ps:=search_struct_member(java_ansistring,'INTERNCHARS');
         if not assigned(ps) or
-           (ps.typ<>propertysym) then
+           (ps.typ<>procsym) then
           internalerror(2011081401);
-        ps:=tpropertysym(ps).propaccesslist[palt_read].firstsym^.sym;
-        if (ps.typ<>procsym) then
-          internalerror(2011081402);
-        result:=ccallnode.create(nil,tprocsym(ps),ps.owner,result,[]);
+        { AnsistringClass.internChars is a static class method that will either
+          return the internal fdata ansichar array of the string, or an array
+          with a single #0 }
+        result:=ccallnode.create(ccallparanode.create(left,nil),tprocsym(ps),
+          ps.owner,
+          cloadvmtaddrnode.create(ctypenode.create(java_ansistring)),[]);
         include(result.flags,nf_isproperty);
         result:=ctypeconvnode.create_explicit(result,resultdef);
         { reused }
@@ -565,13 +566,30 @@ implementation
 
 
     procedure tjvmtypeconvnode.second_cstring_to_pchar;
+      var
+        hr: treference;
+        vs: tstaticvarsym;
       begin
         { don't use is_chararray because it doesn't support special arrays }
         if (left.resultdef.typ<>arraydef) or
            (tarraydef(left.resultdef).elementdef.typ<>orddef) or
            (torddef(tarraydef(left.resultdef).elementdef).ordtype<>uchar) then
           internalerror(2011081304);
-        location_copy(location,left.location);
+        if (tstringconstnode(left).cst_type in [cst_widestring,cst_unicodestring,cst_ansistring]) and
+           (tstringconstnode(left).len=0) then
+          begin
+            if tstringconstnode(left).cst_type=cst_ansistring then
+              vs:=tstaticvarsym(systemunit.Find('EMPTYPANSICHAR'))
+            else
+              vs:=tstaticvarsym(systemunit.Find('EMPTYPWIDECHAR'));
+            reference_reset(hr,4);
+            hr.symbol:=current_asmdata.RefAsmSymbol(vs.mangledname);
+            location_reset(location,LOC_REGISTER,OS_ADDR);
+            location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,resultdef);
+            hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,vs.vardef,resultdef,hr,location.register);
+          end
+        else
+          location_copy(location,left.location);
       end;
 
 

+ 1 - 1
rtl/java/jastringh.inc

@@ -41,7 +41,7 @@ type
     function length: jint;
     function codePage: TSystemCodePage;
     function elementSize: Word;
-    property internChars: TAnsiCharArray read fdata;
+    class function internChars(const a: Ansistring): TAnsiCharArray; static;
   end;
 
 

+ 11 - 0
rtl/java/jastrings.inc

@@ -210,6 +210,17 @@ begin
   result:=fElementSize;
 end;
 
+
+class function AnsistringClass.internChars(const a: Ansistring): TAnsiCharArray;
+begin
+  if a<>'' then
+    result:=AnsistringClass(a).fdata
+  else
+    { empty pchar: array with one element that is #0 }
+    setlength(result,1);
+end;
+
+
 {****************************************************************************
                     Internal functions, not in interface.
 ****************************************************************************}

+ 3 - 2
rtl/java/jsystem.inc

@@ -98,8 +98,9 @@ const
 
 { Used by the ansi/widestrings and maybe also other things in the future }
 var
-  { widechar, because also used by widestring -> pwidechar conversions }
-  emptychar : widechar;public name 'FPC_EMPTYCHAR';
+  { separated compared to generic version, for Java type safety }
+  emptypansichar : array[0..0] of ansichar; public name 'FPC_EMPTYANSICHAR';
+  emptypwidechar : array[0..0] of widechar; public name 'FPC_EMPTYWIDECHAR';
 {$ifndef FPC_NO_GENERIC_STACK_CHECK}
   { if the OS does the stack checking, we don't need any stklen from the
     main program }