• Delphi -- Compiler helper for initializing/finalizing variable


      1 it CompilerhelperForInitializingFinalizingVariable;
      2 
      3 interface
      4 
      5 { Compiler helper for initializing/finalizing variable }
      6 
      7 procedure _Initialize(p : Pointer; typeInfo : Pointer);
      8 procedure _InitializeArray(p : Pointer; typeInfo : Pointer; elemCount : NativeUInt);
      9 procedure _InitializeRecord(p : Pointer; typeInfo : Pointer);
     10 
     11   {$IF not defined(X86ASMRTL)}
     12   // dcc64 generated code expects P to remain in RAX on exit from this function.
     13 function _Finalize(P : Pointer; TypeInfo : Pointer): Pointer;
     14 function _FinalizeArray(P : Pointer; TypeInfo : Pointer; ElemCount : NativeUInt): Pointer;
     15 function _FinalizeRecord(P : Pointer; TypeInfo : Pointer): Pointer;
     16   {$ELSE}
     17 procedure _Finalize(p : Pointer; typeInfo : Pointer);
     18 procedure _FinalizeArray(P : Pointer; TypeInfo : Pointer; ElemCount : NativeUInt);
     19 procedure _FinalizeRecord(P : Pointer; TypeInfo : Pointer);
     20   {$ENDIF}
     21 
     22 procedure _CopyRecord(Dest, Source, TypeInfo : Pointer);
     23 procedure _CopyObject(Dest, Source : Pointer; vmtPtrOffs : NativeInt; TypeInfo : Pointer);
     24 procedure _CopyArray(Dest, Source, TypeInfo : Pointer; Count : NativeUInt);
     25 
     26 procedure _AddRef(P : Pointer; TypeInfo : Pointer);
     27 procedure _AddRefArray(P : Pointer; TypeInfo : Pointer; ElemCount : NativeUInt);
     28 procedure _AddRefRecord(P : Pointer; TypeInfo : Pointer);
     29 
     30 function _New(Size : NativeInt; TypeInfo : Pointer): Pointer;
     31 procedure _Dispose(P : Pointer; TypeInfo : Pointer);
     32 
     33 procedure InitializeArray(p : Pointer; typeInfo : Pointer; elemCount : NativeUInt);
     34 procedure CopyArray(Dest, Source, TypeInfo : Pointer; Count : NativeInt);
     35 procedure FinalizeArray(P : Pointer; TypeInfo : Pointer; Count : NativeUInt);
     36 
     37 
     38 implementation
     39 
     40 { ===========================================================================
     41   InitializeRecord, InitializeArray, and Initialize are PIC safe even though
     42   they alter EBX because they only call each other.  They never call out to
     43   other functions and they don t access global data.
     44 
     45   FinalizeRecord, Finalize, and FinalizeArray are PIC safe because they call
     46   Pascal routines which will have EBX fixup prologs.
     47   ===========================================================================}
     48 procedure _VarClr(var v : TVarData);
     49 begin
     50   if Assigned(VarClearProc) then
     51     VarClearProc(v)
     52   else
     53     Error(reVarInvalidOp);
     54 end;
     55 
     56 procedure _VarCopy(var Dest : TVarData; const Src : TVarData);
     57 begin
     58   if Assigned(VarCopyProc) then
     59     VarCopyProc(Dest, Src)
     60   else
     61     Error(reVarInvalidOp);
     62 end;
     63 
     64 procedure _VarAddRef(var v : TVarData);
     65 begin
     66   if Assigned(VarAddRefProc) then
     67     VarAddRefProc(v)
     68   else
     69     Error(reVarInvalidOp);
     70 end;
     71 
     72 { ===========================================================================
     73   InitializeRecord, InitializeArray, and Initialize are PIC safe even though
     74   they alter EBX because they only call each other.  They never call out to
     75   other functions and they don t access global data.
     76 
     77   FinalizeRecord, Finalize, and FinalizeArray are PIC safe because they call
     78   Pascal routines which will have EBX fixup prologs.
     79   ===========================================================================}
     80       
     81 procedure _InitializeRecord(p : Pointer; typeInfo : Pointer);
     82 var
     83   FT : PFieldTable;
     84   I : Cardinal;
     85 begin
     86   FT := PFieldTable(PByte(typeInfo) + Byte(PTypeInfo(typeInfo).Name[0]));
     87   if FT.Count > 0 then
     88   begin
     89     for I := FT.Count - 1 downto 0 do
     90       {$IFDEF WEAKREF}
     91       if FT.Fields[I].TypeInfo <> nil then
     92         {$ENDIF}
     93         _InitializeArray(Pointer(PByte(P) + UIntPtr(FT.Fields[I].Offset)),
     94           FT.Fields[I].TypeInfo^, 1);
     95   end;
     96 end;
     97 
     98 function _FinalizeRecord(P : Pointer; TypeInfo : Pointer): Pointer;
     99 var
    100   FT : PFieldTable;
    101   I : Cardinal;
    102   {$IFDEF WEAKREF}
    103   Weak : Boolean;
    104   {$ENDIF}
    105 begin
    106   FT := PFieldTable(PByte(TypeInfo) + Byte(PTypeInfo(TypeInfo).Name[0]));
    107   if FT.Count > 0 then
    108   begin
    109     {$IFDEF WEAKREF}
    110     Weak := false;
    111     {$ENDIF}
    112     for I := 0 to FT.Count - 1 do
    113     begin
    114       {$IFDEF WEAKREF}
    115       if FT.Fields[I].TypeInfo = nil then
    116       begin
    117         Weak := true;
    118         Continue;
    119       end;
    120       if not Weak then
    121       begin
    122         {$ENDIF}
    123         _FinalizeArray(Pointer(PByte(P) + IntPtr(FT.Fields[I].Offset)),
    124           FT.Fields[I].TypeInfo^, 1);
    125         {$IFDEF WEAKREF}
    126       end 
    127       else
    128       begin
    129         case FT.Fields[I].TypeInfo^.Kind of
    130           {$IFDEF WEAKINTFREF}
    131           tkInterface: 
    132             _IntfWeakClear(IInterface(Pointer(PByte(P) +
    133               IntPtr(FT.Fields[I].Offset))^));
    134           {$ENDIF}
    135           {$IFDEF WEAKINSTREF}
    136           tkClass: 
    137             _InstWeakClear(TObject(Pointer(PByte(P) + IntPtr(FT.Fields[I].Offset))^));
    138           {$ENDIF}
    139           {$IFDEF WEAKREF}
    140           tkMethod: 
    141             _ClosureRemoveWeakRef(TMethod(Pointer(PByte(P) +
    142               IntPtr(FT.Fields[I].Offset))^));
    143           {$ENDIF}
    144           else
    145             Error(reInvalidPtr);
    146         end;
    147       end;
    148       {$ENDIF}
    149     end;
    150   end;
    151   Result := P;
    152 end;
    153 
    154 procedure _InitializeArray(p : Pointer; typeInfo : Pointer; elemCount : NativeUInt);
    155 var
    156   FT : PFieldTable;
    157   I : Cardinal;
    158 begin
    159   if elemCount = 0 then 
    160     Exit;
    161   case PTypeInfo(typeInfo).Kind of
    162     {$IFDEF WEAKREF}
    163     tkMethod:
    164       while elemCount > 0 do
    165       begin
    166         TMethod(P^).Data := nil;
    167         TMethod(P^).Code := nil;
    168         Inc(PByte(P), SizeOf(TMethod));
    169         Dec(elemCount);
    170       end;
    171     {$ENDIF}
    172     {$IFDEF AUTOREFCOUNT}
    173     tkClass,
    174     {$ENDIF}
    175     tkLString, tkWString, tkInterface, tkDynArray, tkUString:
    176       while elemCount > 0 do
    177       begin
    178         PPointer(P)^ := nil;
    179         Inc(PByte(P), SizeOf(Pointer));
    180         Dec(elemCount);
    181       end;
    182     tkVariant:
    183       while elemCount > 0 do
    184       begin
    185         with PVarData(P)^ do
    186           for I := Low(RawData) to High(RawData) do 
    187             RawData[I] := 0;
    188         Inc(PByte(P), SizeOf(TVarData));
    189         Dec(elemCount);
    190       end;
    191     tkArray:
    192       begin
    193         FT := PFieldTable(PByte(typeInfo) + Byte(PTypeInfo(typeInfo).Name[0]));
    194         while elemCount > 0 do
    195         begin
    196           _InitializeArray(P, FT.Fields[0].TypeInfo^, FT.Count);
    197           Inc(PByte(P), FT.Size);
    198           Dec(elemCount);
    199         end;
    200       end;
    201     tkRecord:
    202       begin
    203         FT := PFieldTable(PByte(typeInfo) + Byte(PTypeInfo(typeInfo).Name[0]));
    204         while elemCount > 0 do
    205         begin
    206           _InitializeRecord(P, typeInfo);
    207           Inc(PByte(P), FT.Size);
    208           Dec(elemCount);
    209         end;
    210       end;
    211     else
    212       Error(reInvalidPtr);
    213   end;
    214 end;
    215 
    216 function _FinalizeArray(P : Pointer; TypeInfo : Pointer; ElemCount : NativeUInt): Pointer;
    217 var
    218   FT : PFieldTable;
    219 begin
    220   Result := P;
    221   if ElemCount = 0 then 
    222     Exit;
    223   case PTypeInfo(TypeInfo).Kind of
    224     {$IFDEF WEAKREF}
    225     tkMethod:
    226       while ElemCount > 0 do
    227       begin
    228         _ClosureRemoveWeakRef(TMethod(P^));
    229         Inc(PByte(P), SizeOf(TMethod));
    230         Dec(ElemCount);
    231       end;
    232     {$ENDIF}
    233     {$IFDEF AUTOREFCOUNT}
    234     tkClass:
    235       while ElemCount > 0 do
    236       begin
    237         _InstClear(TObject(P^));
    238         Inc(PByte(P), SizeOf(Pointer));
    239         Dec(ElemCount);
    240       end;
    241     {$ENDIF}
    242     tkLString: 
    243       _LStrArrayClr(P^, ElemCount);
    244     tkWString: 
    245       _WStrArrayClr(P^, ElemCount);
    246     tkUString: 
    247       _UStrArrayClr(P^, ElemCount);
    248     tkVariant:
    249       while ElemCount > 0 do
    250       begin
    251         _VarClr(PVarData(P)^);
    252         Inc(PByte(P), SizeOf(TVarData));
    253         Dec(ElemCount);
    254       end;
    255     tkArray:
    256       begin
    257         FT := PFieldTable(PByte(typeInfo) + Byte(PTypeInfo(typeInfo).Name[0]));
    258         while ElemCount > 0 do
    259         begin
    260           _FinalizeArray(P, FT.Fields[0].TypeInfo^, FT.Count);
    261           Inc(PByte(P), FT.Size);
    262           Dec(ElemCount);
    263         end;
    264       end;
    265     tkRecord:
    266       begin
    267         FT := PFieldTable(PByte(TypeInfo) + Byte(PTypeInfo(TypeInfo).Name[0]));
    268         while ElemCount > 0 do
    269         begin
    270           _FinalizeRecord(P, TypeInfo);
    271           Inc(PByte(P), FT.Size);
    272           Dec(ElemCount);
    273         end;
    274       end;
    275     tkInterface:
    276       while ElemCount > 0 do
    277       begin
    278         _IntfClear(IInterface(P^));
    279         Inc(PByte(P), SizeOf(Pointer));
    280         Dec(ElemCount);
    281       end;
    282     tkDynArray:
    283       while ElemCount > 0 do
    284       begin
    285         { The cast and dereference of P here is to fake out the call to
    286           _DynArrayClear.  That function expects a var parameter.  Our
    287           declaration says we got a non-var parameter, but because of
    288           the data type that got passed to us (tkDynArray), this isn t
    289           strictly true.  The compiler will have passed us a reference. }
    290         _DynArrayClear(PPointer(P)^, typeInfo);
    291         Inc(PByte(P), SizeOf(Pointer));
    292         Dec(ElemCount);
    293       end;
    294     else
    295       Error(reInvalidPtr);
    296   end;
    297 end;
    298 
    299 procedure _AddRefRecord(P : Pointer; TypeInfo : Pointer);
    300 var
    301   FT : PFieldTable;
    302   I : Cardinal;
    303 begin
    304   FT := PFieldTable(PByte(TypeInfo) + Byte(PTypeInfo(TypeInfo).Name[0]));
    305   if FT.Count > 0 then
    306   begin
    307     for I := 0 to FT.Count - 1 do
    308     begin
    309       {$IFDEF WEAKREF}
    310       // Check for the sentinal indicating the following fields are weak references
    311       // which don t need to be reference counted
    312       if FT.Fields[I].TypeInfo = nil then
    313         Break;
    314       {$ENDIF}
    315       _AddRefArray(Pointer(PByte(P) + UIntPtr(FT.Fields[I].Offset)),
    316         FT.Fields[I].TypeInfo^, 1);
    317     end;
    318   end;
    319 end;
    320 
    321 procedure _AddRefArray(P : Pointer; TypeInfo : Pointer; ElemCount : NativeUInt);
    322 var
    323   FT : PFieldTable;
    324 begin
    325   if ElemCount = 0 then 
    326     Exit;
    327   case PTypeInfo(TypeInfo).Kind of
    328     {$IFDEF WEAKREF}
    329     tkMethod:
    330       while ElemCount > 0 do
    331       begin
    332         _ClosureAddWeakRef(TMethod(P^));
    333         Inc(PByte(P), SizeOf(TMethod));
    334         Dec(ElemCount);
    335       end;
    336     {$ENDIF}
    337     {$IFDEF AUTOREFCOUNT}
    338     tkClass:
    339       while ElemCount > 0 do
    340       begin
    341         _InstAddRef(TObject(P^));
    342         Inc(PByte(P), SizeOf(Pointer));
    343         Dec(ElemCount);
    344       end;
    345     {$ENDIF}
    346     tkLString:
    347       while ElemCount > 0 do
    348       begin
    349         _LStrAddRef(PPointer(P)^);
    350         Inc(PByte(P), SizeOf(Pointer));
    351         Dec(ElemCount);
    352       end;
    353     tkWString:
    354       while ElemCount > 0 do
    355       begin
    356         {$IFDEF MSWINDOWS}
    357         _WStrAddRef(PWideString(P)^);
    358         {$ELSE}
    359         _WStrAddRef(PPointer(P)^);
    360         {$ENDIF}
    361         Inc(PByte(P), SizeOf(Pointer));
    362         Dec(ElemCount);
    363       end;
    364     tkUString:
    365       while ElemCount > 0 do
    366       begin
    367         _UStrAddRef(PPointer(P)^);
    368         Inc(PByte(P), SizeOf(Pointer));
    369         Dec(ElemCount);
    370       end;
    371     tkVariant:
    372       while ElemCount > 0 do
    373       begin
    374         _VarAddRef(PVarData(P)^);
    375         Inc(PByte(P), SizeOf(TVarData));
    376         Dec(ElemCount);
    377       end;
    378     tkArray:
    379       begin
    380         FT := PFieldTable(PByte(TypeInfo) + Byte(PTypeInfo(TypeInfo).Name[0]));
    381         while ElemCount > 0 do
    382         begin
    383           _AddRefArray(P, FT.Fields[0].TypeInfo^, FT.Count);
    384           Inc(PByte(P), FT.Size);
    385           Dec(ElemCount);
    386         end;
    387       end;
    388     tkRecord:
    389       begin
    390         FT := PFieldTable(PByte(TypeInfo) + Byte(PTypeInfo(TypeInfo).Name[0]));
    391         while ElemCount > 0 do
    392         begin
    393           _AddRefRecord(P, TypeInfo);
    394           Inc(PByte(P), FT.Size);
    395           Dec(ElemCount);
    396         end;
    397       end;
    398     tkInterface:
    399       while ElemCount > 0 do
    400       begin
    401         _IntfAddRef(IInterface(P^));
    402         Inc(PByte(P), SizeOf(Pointer));
    403         Dec(ElemCount);
    404       end;
    405     tkDynArray:
    406       while ElemCount > 0 do
    407       begin
    408         _DynArrayAddRef(PPointer(P)^);
    409         Inc(PByte(P), SizeOf(Pointer));
    410         Dec(ElemCount);
    411       end;
    412     else
    413       Error(reInvalidPtr);
    414   end;
    415 end;
    416 
    417 procedure _AddRef(P : Pointer; TypeInfo : Pointer);
    418 begin
    419   _AddRefArray(P, TypeInfo, 1);
    420 end;
    421 
    422 procedure _CopyRecord(Dest, Source, TypeInfo : Pointer);
    423 var
    424   FT, EFT : PFieldTable;
    425   I, Count, L : Cardinal;
    426   {$IFDEF WEAKREF}
    427   J, K : Cardinal;
    428   {$ENDIF}
    429   Offset : UIntPtr;
    430   FTypeInfo : PTypeInfo;
    431   DestOff, SrcOff : Pointer;
    432 begin
    433   FT := PFieldTable(PByte(TypeInfo) + Byte(PTypeInfo(TypeInfo).Name[0]));
    434   Offset := 0;
    435   if FT.Count > 0 then
    436   begin
    437     Count := FT.Count;
    438     {$IFDEF WEAKREF}
    439     J := 0;
    440     K := Count;
    441     for I := Count - 1 downto 0 do
    442       if FT.Fields[I].TypeInfo = nil then
    443       begin
    444         K := I + 1; // found the weak sentinal
    445         Dec(Count); // remove the sentinal from consideration
    446         Break;
    447       end;
    448     {$ENDIF}
    449     for L := 0 to Count - 1 do
    450     begin
    451       {$IFDEF WEAKREF}
    452       if (FT.Fields[J].TypeInfo <> nil) and
    453         ((K = FT.Count) or (FT.Fields[J].Offset < FT.Fields[K].Offset)) then
    454       begin
    455         I := J;
    456         Inc(J);
    457       end 
    458       else
    459       begin
    460         I := K;
    461         Inc(K);
    462       end;
    463       {$ELSE}
    464       I := L;
    465       {$ENDIF}
    466       if FT.Fields[I].Offset > Offset then
    467         Move(Pointer(PByte(Source) + Offset)^,
    468           Pointer(PByte(Dest) + Offset)^,
    469           FT.Fields[I].Offset - Offset);
    470       Offset := FT.Fields[I].Offset;
    471       FTypeInfo := FT.Fields[I].TypeInfo^;
    472       DestOff := Pointer(PByte(Dest) + Offset);
    473       SrcOff := Pointer(PByte(Source) + Offset);
    474       case FTypeInfo.Kind of
    475         {$IFDEF WEAKREF}
    476         tkMethod:
    477           begin
    478             _CopyClosure(PMethod(DestOff)^, PMethod(SrcOff)^);
    479             Inc(Offset, SizeOf(TMethod));
    480           end;
    481         {$ENDIF}
    482         {$IFDEF AUTOREFCOUNT}
    483         tkClass:
    484           begin
    485             {$IFDEF WEAKINSTREF}
    486             if I > J then
    487               _InstWeakCopy(TObject(PPointer(DestOff)^),
    488                 TObject(PPointer(SrcOff)^))
    489             else
    490               {$ENDIF}
    491               _InstCopy(TObject(PPointer(DestOff)^), TObject(PPointer(SrcOff)^));
    492             Inc(Offset, SizeOf(Pointer));
    493           end;
    494         {$ENDIF}
    495         tkLString:
    496           begin
    497             _LStrAsg(_PAnsiStr(DestOff)^, _PAnsiStr(SrcOff)^);
    498             Inc(Offset, SizeOf(Pointer));
    499           end;
    500         tkWString:
    501           begin
    502             _WStrAsg(_PWideStr(DestOff)^, _PWideStr(SrcOff)^);
    503             Inc(Offset, SizeOf(Pointer));
    504           end;
    505         tkUString:
    506           begin
    507             _UStrAsg(PUnicodeString(DestOff)^, PUnicodeString(SrcOff)^);
    508             Inc(Offset, SizeOf(Pointer));
    509           end;
    510         tkVariant:
    511           begin
    512             _VarCopy(PVarData(DestOff)^, PVarData(SrcOff)^);
    513             Inc(Offset, SizeOf(TVarData));
    514           end;
    515         tkArray:
    516           begin
    517             EFT :=
    518               PFieldTable(PByte(FTypeInfo) + Byte(PTypeInfo(FTypeInfo).Name[0]));
    519             _CopyArray(DestOff, SrcOff, EFT.Fields[0].TypeInfo^, EFT.Count);
    520             Inc(Offset, EFT.Size);
    521           end;
    522         tkRecord:
    523           begin
    524             EFT :=
    525               PFieldTable(PByte(FTypeInfo) + Byte(PTypeInfo(FTypeInfo).Name[0]));
    526             _CopyRecord(DestOff, SrcOff, FTypeInfo);
    527 
    528             Inc(Offset, EFT.Size);
    529           end;
    530         tkInterface:
    531           begin
    532             {$IFDEF WEAKINTFREF}
    533             if I > J then
    534               _IntfWeakCopy(IInterface(PPointer(DestOff)^),
    535                 IInterface(PPointer(SrcOff)^))
    536             else
    537               {$ENDIF}
    538               _IntfCopy(IInterface(PPointer(DestOff)^),
    539                 IInterface(PPointer(SrcOff)^));
    540             Inc(Offset, SizeOf(Pointer));
    541           end;
    542         tkDynArray:
    543           begin
    544             _DynArrayAsg(PPointer(DestOff)^, PPointer(SrcOff)^, FTypeInfo);
    545             Inc(Offset, SizeOf(Pointer));
    546           end;
    547         else
    548           Error(reInvalidPtr);
    549       end;
    550     end;
    551   end;
    552   if FT.Size > Offset then
    553     Move(Pointer(PByte(Source) + Offset)^,
    554       Pointer(PByte(Dest) + Offset)^,
    555       FT.Size - Offset);
    556 end;
    557 
    558 procedure _CopyObject(Dest, Source : Pointer; vmtPtrOffs : NativeInt; TypeInfo : Pointer);
    559 var
    560   SavedVmtPtr : Pointer;
    561 begin
    562   SavedVmtPtr := PPointer(PByte(Dest) + vmtPtrOffs)^;
    563   _CopyRecord(Dest, Source, TypeInfo);
    564   PPointer(PByte(Dest) + vmtPtrOffs)^ := SavedVmtPtr;
    565 end;
    566 
    567 procedure _CopyArray(Dest, Source, TypeInfo : Pointer; Count : NativeUInt);
    568 var
    569   FT : PFieldTable;
    570 begin
    571   if Count = 0 then 
    572     Exit;
    573   case PTypeInfo(TypeInfo).Kind of
    574     {$IFDEF WEAKREF}
    575     tkMethod:
    576       while Count > 0 do
    577       begin
    578         _CopyClosure(PMethod(Dest)^, PMethod(Source)^);
    579         Inc(PByte(Dest), SizeOf(TMethod));
    580         Inc(PByte(Source), SizeOf(TMethod));
    581         Dec(Count);
    582       end;
    583     {$ENDIF}
    584     {$IFDEF AUTOREFCOUNT}
    585     tkClass:
    586       while Count > 0 do
    587       begin
    588         _InstCopy(TObject(PPointer(Dest)^), TObject(PPointer(Source)^));
    589         Inc(PByte(Dest), SizeOf(Pointer));
    590         Inc(PByte(Source), SizeOf(Pointer));
    591         Dec(Count);
    592       end;
    593     {$ENDIF}
    594     tkLString:
    595       while Count > 0 do
    596       begin
    597         _LStrAsg(_PAnsiStr(Dest)^, _PAnsiStr(Source)^);
    598         Inc(PByte(Dest), SizeOf(Pointer));
    599         Inc(PByte(Source), SizeOf(Pointer));
    600         Dec(Count);
    601       end;
    602     tkWString:
    603       while Count > 0 do
    604       begin
    605         _WStrAsg(_PWideStr(Dest)^, _PWideStr(Source)^);
    606         Inc(PByte(Dest), SizeOf(Pointer));
    607         Inc(PByte(Source), SizeOf(Pointer));
    608         Dec(Count);
    609       end;
    610     tkUString:
    611       while Count > 0 do
    612       begin
    613         _UStrAsg(PUnicodeString(Dest)^, PUnicodeString(Source)^);
    614         Inc(PByte(Dest), SizeOf(Pointer));
    615         Inc(PByte(Source), SizeOf(Pointer));
    616         Dec(Count);
    617       end;
    618     tkVariant:
    619       while Count > 0 do
    620       begin
    621         _VarCopy(PVarData(Dest)^, PVarData(Source)^);
    622         Inc(PByte(Dest), SizeOf(TVarData));
    623         Inc(PByte(Source), SizeOf(TVarData));
    624         Dec(Count);
    625       end;
    626     tkArray:
    627       begin
    628         FT := PFieldTable(PByte(TypeInfo) + Byte(PTypeInfo(TypeInfo).Name[0]));
    629         while Count > 0 do
    630         begin
    631           _CopyArray(Pointer(Dest), Pointer(Source),
    632             FT.Fields[0].TypeInfo^, FT.Count);
    633           Inc(PByte(Dest), FT.Size);
    634           Inc(PByte(Source), FT.Size);
    635           Dec(Count);
    636         end;
    637       end;
    638     tkRecord:
    639       begin
    640         FT := PFieldTable(PByte(TypeInfo) + Byte(PTypeInfo(TypeInfo).Name[0]));
    641         while Count > 0 do
    642         begin
    643           _CopyRecord(Dest, Source, TypeInfo);
    644           Inc(PByte(Dest), FT.Size);
    645           Inc(PByte(Source), FT.Size);
    646           Dec(Count);
    647         end;
    648       end;
    649     tkInterface:
    650       while Count > 0 do
    651       begin
    652         _IntfCopy(IInterface(PPointer(Dest)^), IInterface(PPointer(Source)^));
    653         Inc(PByte(Dest), SizeOf(Pointer));
    654         Inc(PByte(Source), SizeOf(Pointer));
    655         Dec(Count);
    656       end;
    657     tkDynArray:
    658       while Count > 0 do
    659       begin
    660         _DynArrayAsg(PPointer(Dest)^, PPointer(Source)^, TypeInfo);
    661         Inc(PByte(Dest), SizeOf(Pointer));
    662         Inc(PByte(Source), SizeOf(Pointer));
    663         Dec(Count);
    664       end;
    665     else
    666       Error(reInvalidPtr);
    667   end;
    668 end;
    669 
    670 procedure CopyArray(Dest, Source, TypeInfo : Pointer; Count : NativeInt);
    671 begin
    672   if Count > 0 then
    673     _CopyArray(Dest, Source, TypeInfo, Count);
    674 end;
    675 
    676 procedure InitializeArray(p : Pointer; typeInfo : Pointer; elemCount : NativeUInt);
    677 begin
    678   _InitializeArray(p, typeInfo, elemCount);
    679 end;
    680 
    681 procedure FinalizeArray(P, TypeInfo : Pointer; Count : NativeUInt);
    682 begin
    683   _FinalizeArray(P, TypeInfo, Count);
    684 end;
    685 
    686 procedure _Initialize(p : Pointer; typeInfo : Pointer);
    687 begin
    688   _InitializeArray(p, typeInfo, 1);
    689 end;
    690 
    691 function _Finalize(p : Pointer; typeInfo : Pointer): Pointer;
    692 begin
    693   Result := _FinalizeArray(p, typeInfo, 1);
    694 end;
    695 
    696 function _New(Size : NativeInt; TypeInfo : Pointer): Pointer;
    697 begin
    698   GetMem(Result, Size);
    699   if Result <> nil then
    700     _Initialize(Result, TypeInfo);
    701 end;
    702 
    703 procedure _Dispose(P : Pointer; TypeInfo : Pointer);
    704 begin
    705   _Finalize(P, TypeInfo);
    706   FreeMem(P);
    707 end;
  • 相关阅读:
    转发-》c++ stl multimap基本操作使用技巧详细介绍
    控件传递,待更新
    封装函数获取体的最大4个角
    找vector最大最小《转载》
    获取面面积,资料来自录制和网友分享
    【转】插入排序
    NXOpen获取UFUN的tag
    创建注释
    创建铜公开粗程序
    NXopen create chamfer tool
  • 原文地址:https://www.cnblogs.com/shangdawei/p/5812798.html
Copyright © 2020-2023  润新知