Selaa lähdekoodia

* 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 vuotta sitten
vanhempi
commit
8649788b7f
2 muutettua tiedostoa jossa 42 lisäystä ja 5 poistoa
  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;
         fromdef,
         todef: tdef;
+        fromarrtype,
+        toarrtype: char;
       begin
         result:=nil;
         { 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
               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;
             todef:=resultdef;
             get_most_nested_types(fromdef,todef);
+            fromarrtype:=jvmarrtype_setlength(fromdef);
+            toarrtype:=jvmarrtype_setlength(todef);
             if not left.resultdef.is_related(resultdef) and
                (((fromdef.typ<>objectdef) and
                  not is_dynamic_array(fromdef)) or
-                (todef<>java_jlobject)) then
+                (todef<>java_jlobject)) and
+               ((fromarrtype in ['A','R']) or
+                (fromarrtype<>toarrtype)) then
               begin
                 result:=ctypenode.create(resultdef);
                 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,
           typecast to generic array of tobject }
         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
            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
-            objarraydef:=search_system_type('TJOBJECTARRAY').typedef;
             tcallparanode(newparas).left:=ctypeconvnode.create_explicit(tcallparanode(newparas).left,objarraydef);
             newnode:=ctypeconvnode.create_explicit(newnode,objarraydef);
           end;
@@ -303,7 +332,6 @@ implementation
         { call the right setlenght helper }
         if ndims>1 then
           begin
-            finaltype:=jvmarrtype_setlength(eledef);
             setlenroutine:='FPC_SETLENGTH_DYNARR_MULTIDIM';
             { create proper parameters, from right to left:
                eletype=finaltype, ndim=ndims, deepcopy=false, new=newnode,