Pārlūkot izejas kodu

* typecast the argument and result type of the setlength() helper to
the types as declared in the system unit, since they can also be
used with equivalent but different types (e.g., byte vs shortint)

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

Jonas Maebe 14 gadi atpakaļ
vecāks
revīzija
8649788b7f
2 mainītis faili ar 42 papildinājumiem un 5 dzēšanām
  1. 12 3
      compiler/jvm/njvmcnv.pas
  2. 30 2
      compiler/jvm/njvminl.pas

+ 12 - 3
compiler/jvm/njvmcnv.pas

@@ -442,6 +442,8 @@ implementation
         toclasscompatible: boolean;
         toclasscompatible: boolean;
         fromdef,
         fromdef,
         todef: tdef;
         todef: tdef;
+        fromarrtype,
+        toarrtype: char;
       begin
       begin
         result:=nil;
         result:=nil;
         { This routine is only called for explicit typeconversions of same-sized
         { This routine is only called for explicit typeconversions of same-sized
@@ -467,15 +469,22 @@ implementation
               it wasn't handled by another type conversion, we know it can't
               it wasn't handled by another type conversion, we know it can't
               have been valid normally)
               have been valid normally)
 
 
-              Exception: (most nested) destination is java.lang.Object, since
-                everything is compatible with that type }
+              Exceptions: (most nested) destination is
+                * java.lang.Object, since everything is compatible with that type
+                * related to source
+                * a primitive that are represented by the same type in Java
+                  (e.g., byte and shortint) }
             fromdef:=left.resultdef;
             fromdef:=left.resultdef;
             todef:=resultdef;
             todef:=resultdef;
             get_most_nested_types(fromdef,todef);
             get_most_nested_types(fromdef,todef);
+            fromarrtype:=jvmarrtype_setlength(fromdef);
+            toarrtype:=jvmarrtype_setlength(todef);
             if not left.resultdef.is_related(resultdef) and
             if not left.resultdef.is_related(resultdef) and
                (((fromdef.typ<>objectdef) and
                (((fromdef.typ<>objectdef) and
                  not is_dynamic_array(fromdef)) or
                  not is_dynamic_array(fromdef)) or
-                (todef<>java_jlobject)) then
+                (todef<>java_jlobject)) and
+               ((fromarrtype in ['A','R']) or
+                (fromarrtype<>toarrtype)) then
               begin
               begin
                 result:=ctypenode.create(resultdef);
                 result:=ctypenode.create(resultdef);
                 if resultdef.typ=objectdef then
                 if resultdef.typ=objectdef then

+ 30 - 2
compiler/jvm/njvminl.pas

@@ -289,10 +289,39 @@ implementation
         { if more than 1 dimension, or if 1 dimention of a non-primitive type,
         { if more than 1 dimension, or if 1 dimention of a non-primitive type,
           typecast to generic array of tobject }
           typecast to generic array of tobject }
         setlenroutine:=jvmarrtype(eledef,primitive);
         setlenroutine:=jvmarrtype(eledef,primitive);
+        finaltype:=jvmarrtype_setlength(eledef);
+
+        { since the setlength prototypes require certain types, insert
+          explicit type conversions where necessary }
+        objarraydef:=nil;
+        { all arrays, records and object types need to be handled as JLObject }
         if (ndims>1) or
         if (ndims>1) or
            not primitive then
            not primitive then
+          objarraydef:=search_system_type('TJOBJECTARRAY').typedef
+        { insert type conversion, because this is used both for signed and
+          unsigned types }
+        else case finaltype of
+          'Z': { boolean is always the same };
+          'C': { char is always the same };
+          'B':
+            { jbyte: used for both shortint and byte }
+            objarraydef:=search_system_type('TJBYTEARRAY').typedef;
+          'S':
+            { jshort: used for both smallint and word }
+            objarraydef:=search_system_type('TJSHORTARRAY').typedef;
+          'I':
+            { jshort: used for both smallint and word }
+            objarraydef:=search_system_type('TJINTARRAY').typedef;
+          'J':
+            { jshort: used for both smallint and word }
+            objarraydef:=search_system_type('TJLONGARRAY').typedef;
+          'F': { float is always the same };
+          'D': { double is always the same };
+          else
+            internalerror(2011040705);
+          end;
+        if assigned(objarraydef) then
           begin
           begin
-            objarraydef:=search_system_type('TJOBJECTARRAY').typedef;
             tcallparanode(newparas).left:=ctypeconvnode.create_explicit(tcallparanode(newparas).left,objarraydef);
             tcallparanode(newparas).left:=ctypeconvnode.create_explicit(tcallparanode(newparas).left,objarraydef);
             newnode:=ctypeconvnode.create_explicit(newnode,objarraydef);
             newnode:=ctypeconvnode.create_explicit(newnode,objarraydef);
           end;
           end;
@@ -303,7 +332,6 @@ implementation
         { call the right setlenght helper }
         { call the right setlenght helper }
         if ndims>1 then
         if ndims>1 then
           begin
           begin
-            finaltype:=jvmarrtype_setlength(eledef);
             setlenroutine:='FPC_SETLENGTH_DYNARR_MULTIDIM';
             setlenroutine:='FPC_SETLENGTH_DYNARR_MULTIDIM';
             { create proper parameters, from right to left:
             { create proper parameters, from right to left:
                eletype=finaltype, ndim=ndims, deepcopy=false, new=newnode,
                eletype=finaltype, ndim=ndims, deepcopy=false, new=newnode,