diff --git a/compiler/nld.pas b/compiler/nld.pas index 6b8e5b7582..be1a8ac02b 100644 --- a/compiler/nld.pas +++ b/compiler/nld.pas @@ -698,6 +698,23 @@ implementation exit; end; + { call helpers for composite types containing automated types } + if (left.resultdef.needs_inittable) and + (left.resultdef.typ in [arraydef,objectdef,recorddef]) then + begin + hp:=ccallparanode.create(caddrnode.create_internal( + crttinode.create(tstoreddef(left.resultdef),fullrtti,rdt_normal)), + ccallparanode.create(ctypeconvnode.create_internal( + caddrnode.create_internal(left),voidpointertype), + ccallparanode.create(ctypeconvnode.create_internal( + caddrnode.create_internal(right),voidpointertype), + nil))); + result:=ccallnode.createintern('fpc_copy',hp); + left:=nil; + right:=nil; + exit; + end; + { call helpers for windows widestrings, they aren't ref. counted } if (tf_winlikewidestring in target_info.flags) and is_widestring(left.resultdef) then begin diff --git a/rtl/inc/compproc.inc b/rtl/inc/compproc.inc index 8f6e32ad66..126d2f6490 100644 --- a/rtl/inc/compproc.inc +++ b/rtl/inc/compproc.inc @@ -410,6 +410,7 @@ Procedure fpc_finalize (Data,TypeInfo: Pointer); compilerproc; Procedure fpc_Addref (Data,TypeInfo : Pointer); compilerproc; Procedure fpc_DecRef (Data,TypeInfo : Pointer); compilerproc; procedure fpc_finalize_array(data,typeinfo : pointer;count,size : longint); compilerproc; +procedure fpc_Copy (Src, Dest, TypeInfo : Pointer); compilerproc; {$endif FPC_HAS_FEATURE_RTTI} diff --git a/rtl/inc/rtti.inc b/rtl/inc/rtti.inc index 1abcb23095..61a8283e3e 100644 --- a/rtl/inc/rtti.inc +++ b/rtl/inc/rtti.inc @@ -45,6 +45,7 @@ Const type TRTTIProc=procedure(Data,TypeInfo:Pointer); +{ if you modify this procedure, fpc_copy must be probably modified as well } procedure RecordRTTI(Data,TypeInfo:Pointer;rttiproc:TRTTIProc); { A record is designed as follows : @@ -87,6 +88,7 @@ begin end; +{ if you modify this procedure, fpc_copy must be probably modified as well } procedure ArrayRTTI(Data,TypeInfo:Pointer;rttiproc:TRTTIProc); { An array is designed as follows : @@ -220,15 +222,17 @@ begin end; end; +{ define alias for internal use in the system unit } +Procedure fpc_Copy_internal (Src, Dest, TypeInfo : Pointer);[external name 'FPC_COPY']; -(* Procedure fpc_Copy (Src, Dest, TypeInfo : Pointer);[Public,alias : 'FPC_COPY']; compilerproc; var Temp : pbyte; namelen : byte; count, offset, - i : longint; + size, + i : SizeInt; info : pointer; begin case PByte(TypeInfo)^ of @@ -239,13 +243,26 @@ begin PPointer(Dest)^:=PPointer(Src)^; end; tkWstring: - begin - fpc_WideStr_Incr_Ref(PPointer(Src)^); - fpc_WideStr_Decr_Ref(PPointer(Dest)^); - end; + fpc_WideStr_Assign(PPointer(Dest)^,PPointer(Src)^); tkArray: begin - arrayrtti(data,typeinfo,@fpc_systemDecRef); + Temp:=PByte(TypeInfo); + inc(Temp); + { Skip Name } + namelen:=Temp^; + inc(temp,namelen+1); + temp:=aligntoptr(temp); + { Element size } + size:=PSizeInt(Temp)^; + inc(Temp,sizeof(Size)); + { Element count } + Count:=PSizeInt(Temp)^; + inc(Temp,sizeof(Count)); + Info:=PPointer(Temp)^; + inc(Temp,sizeof(Info)); + { Process elements } + for I:=0 to Count-1 do + fpc_Copy_internal(Src+(I*size),Dest+(I*size),Info); end; tkobject, tkrecord: @@ -265,19 +282,20 @@ begin { Element count } Count:=PLongint(Temp)^; inc(Temp,sizeof(Count)); - { Process elements } + { Process elements with rtti } for i:=1 to count Do begin Info:=PPointer(Temp)^; inc(Temp,sizeof(Info)); Offset:=PLongint(Temp)^; inc(Temp,sizeof(Offset)); - fpc_Copy(Src+Offset,Src+Offset,Info); + fpc_Copy_internal(Src+Offset,Dest+Offset,Info); end; + end; tkDynArray: begin fpc_dynarray_Incr_Ref(PPointer(Src)^); - fpc_dynarray_Decr_Ref(PPointer(Dest)^); + fpc_dynarray_Decr_Ref(PPointer(Dest)^,typeinfo); PPointer(Dest)^:=PPointer(Src)^; end; tkInterface: @@ -290,7 +308,6 @@ begin VarCopyProc(pvardata(dest)^,pvardata(src)^); end; end; -*) procedure fpc_finalize_array(data,typeinfo : pointer;count,size : longint); [Public,Alias:'FPC_FINALIZEARRAY']; compilerproc;