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;

 

你可能感兴趣的:(Delphi -- Compiler helper for initializing/finalizing variable)