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

* Call management operators also for records with zero-size. For that purpose was changed function RTTISize. New name for RTTISize is RTTISizeAndOp. RTTISizeAndOp can return size of required type and information about existing management operators for that type in current context (to determine context is used enum TRTTIRecOpType which is passed also as parameter in RTTISizeAndOp). RTTISizeAndOp is used in fpc_initialize_array, fpc_finalize_array, fpc_addref_array and CopyArray.

git-svn-id: trunk@35451 -
maciej-izak 8 éve
szülő
commit
4154b4ca8a
1 módosított fájl, 64 hozzáadás és 10 törlés
  1. 64 10
      rtl/inc/rtti.inc

+ 64 - 10
rtl/inc/rtti.inc

@@ -166,8 +166,15 @@ begin
 end;
 {$endif FPC_HAS_MANAGEMENT_OPERATORS}
 
+{$ifdef FPC_HAS_MANAGEMENT_OPERATORS}
+function RTTISizeAndOp(typeInfo: Pointer;
+  const expectedManagementOp: TRTTIRecOpType; out hasManagementOp: boolean): SizeInt;
+begin
+  hasManagementOp:=false;
+{$else FPC_HAS_MANAGEMENT_OPERATORS}
 function RTTISize(typeInfo: Pointer): SizeInt;
 begin
+{$endif FPC_HAS_MANAGEMENT_OPERATORS}
   case PByte(typeinfo)^ of
     tkAString,tkWString,tkUString,
     tkInterface,tkDynarray:
@@ -178,8 +185,26 @@ begin
 {$endif FPC_HAS_FEATURE_VARIANTS}
     tkArray:
       result:=RTTIArraySize(typeinfo);
+{$ifdef FPC_HAS_MANAGEMENT_OPERATORS}
+    tkObject:
+      result:=RTTIRecordSize(typeinfo);
+    tkRecord:
+      with RTTIRecordOp(typeInfo,typeInfo)^ do
+        begin
+          result:=Size;
+          hasManagementOp := Assigned(RecordOp);
+          if hasManagementOp then
+            case expectedManagementOp of
+              rotInitialize: hasManagementOp:=Assigned(RecordOp^.Initialize);
+              rotFinalize: hasManagementOp:=Assigned(RecordOp^.Finalize);
+              rotAddRef: hasManagementOp:=Assigned(RecordOp^.AddRef);
+              rotCopy: hasManagementOp:=Assigned(RecordOp^.Copy);
+            end;
+        end;
+{$else FPC_HAS_MANAGEMENT_OPERATORS}
     tkObject,tkRecord:
       result:=RTTIRecordSize(typeinfo);
+{$endif FPC_HAS_MANAGEMENT_OPERATORS}
   else
     result:=-1;
   end;
@@ -517,31 +542,53 @@ end;
 
 procedure fpc_initialize_array(data,typeinfo : pointer;count : SizeInt); [public,alias:'FPC_INITIALIZE_ARRAY']; compilerproc;
   var
-     i, size : SizeInt;
+    i, size : SizeInt;
+{$ifdef FPC_HAS_MANAGEMENT_OPERATORS}
+    hasManagementOp: boolean;
+  begin
+    size:=RTTISizeAndOp(typeinfo, rotInitialize, hasManagementOp);
+    if (size>0) or hasManagementOp then
+{$else FPC_HAS_MANAGEMENT_OPERATORS}
   begin
-     size:=RTTISize(typeinfo);
-     if size>0 then
-       for i:=0 to count-1 do
-         int_initialize(data+size*i,typeinfo);
+    size:=RTTISize(typeInfo);
+    if size>0 then
+{$endif FPC_HAS_MANAGEMENT_OPERATORS}
+      for i:=0 to count-1 do
+        int_initialize(data+size*i,typeinfo);
   end;
 
 
 procedure fpc_finalize_array(data,typeinfo : pointer;count : SizeInt); [Public,Alias:'FPC_FINALIZE_ARRAY'];  compilerproc;
   var
      i, size: SizeInt;
+{$ifdef FPC_HAS_MANAGEMENT_OPERATORS}
+    hasManagementOp: boolean;
   begin
-     size:=RTTISize(typeinfo);
-     if size>0 then
-       for i:=0 to count-1 do
-         int_finalize(data+size*i,typeinfo);
+    size:=RTTISizeAndOp(typeinfo, rotFinalize, hasManagementOp);
+    if (size>0) or hasManagementOp then
+{$else FPC_HAS_MANAGEMENT_OPERATORS}
+  begin
+    size:=RTTISize(typeInfo);
+    if size>0 then
+{$endif FPC_HAS_MANAGEMENT_OPERATORS}
+      for i:=0 to count-1 do
+        int_finalize(data+size*i,typeinfo);
   end;
 
+
 procedure fpc_addref_array(data,typeinfo: pointer; count: SizeInt); [public,alias:'FPC_ADDREF_ARRAY']; compilerproc;
   var
     i, size: SizeInt;
+{$ifdef FPC_HAS_MANAGEMENT_OPERATORS}
+    hasManagementOp: boolean;
   begin
-    size:=RTTISize(typeinfo);
+    size:=RTTISizeAndOp(typeinfo, rotAddRef, hasManagementOp);
+    if (size>0) or hasManagementOp then
+{$else FPC_HAS_MANAGEMENT_OPERATORS}
+  begin
+    size:=RTTISize(typeInfo);
     if size>0 then
+{$endif FPC_HAS_MANAGEMENT_OPERATORS}
       for i:=0 to count-1 do
         int_addref(data+size*i,typeinfo);
   end;
@@ -566,9 +613,16 @@ procedure FinalizeArray(p, typeInfo: Pointer; count: SizeInt);
 procedure CopyArray(dest, source, typeInfo: Pointer; count: SizeInt);
   var
     i, size: SizeInt;
+{$ifdef FPC_HAS_MANAGEMENT_OPERATORS}
+    hasManagementOp: boolean;
+  begin
+    size:=RTTISizeAndOp(typeinfo, rotCopy, hasManagementOp);
+    if (size>0) or hasManagementOp then
+{$else FPC_HAS_MANAGEMENT_OPERATORS}
   begin
     size:=RTTISize(typeInfo);
     if size>0 then
+{$endif FPC_HAS_MANAGEMENT_OPERATORS}
       for i:=0 to count-1 do
         fpc_Copy_internal(source+size*i, dest+size*i, typeInfo);
   end;