diff options
-rw-r--r-- | compiler/arm/cpupara.pas | 39 | ||||
-rw-r--r-- | compiler/i386/cpupara.pas | 24 | ||||
-rw-r--r-- | compiler/ncgrtti.pas | 211 | ||||
-rw-r--r-- | compiler/options.pas | 1 | ||||
-rw-r--r-- | compiler/paramgr.pas | 8 | ||||
-rw-r--r-- | compiler/x86_64/cpupara.pas | 61 | ||||
-rw-r--r-- | rtl/objpas/typinfo.pp | 91 |
7 files changed, 348 insertions, 87 deletions
diff --git a/compiler/arm/cpupara.pas b/compiler/arm/cpupara.pas index 1d43e97119..1b0115ce5e 100644 --- a/compiler/arm/cpupara.pas +++ b/compiler/arm/cpupara.pas @@ -37,6 +37,7 @@ unit cpupara; function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override; function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override; function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override; + procedure get_para_regoff(proccalloption: tproccalloption; paraloc: pcgparalocation; out reg: Byte; out off: LongInt);override; function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override; function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override; procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override; @@ -74,6 +75,44 @@ unit cpupara; result:=VOLATILE_FPUREGISTERS; end; + procedure tcpuparamanager.get_para_regoff(proccalloption: tproccalloption; paraloc: pcgparalocation; out reg: Byte; out off: LongInt); + var + I : SizeInt; + begin + with paraloc^ do + case loc of + LOC_REGISTER: + begin + reg:=getsupreg(register)-RS_R0; + off:=0; + end; + LOC_FPUREGISTER: + begin + reg:=getsupreg(register)-RS_F0; + off:=0; + end; + LOC_MMREGISTER: + begin + reg:=getsupreg(register); + if reg < RS_S1 then + begin + reg:=reg-RS_D0; + off:=0; + end + else + begin + reg:=reg-RS_S1; + off:=4; + end; + end; + LOC_REFERENCE: + begin + reg:=255; + off:=reference.offset; + end; + end; + end; + function tcpuparamanager.get_volatile_registers_mm(calloption: tproccalloption): tcpuregisterset; begin diff --git a/compiler/i386/cpupara.pas b/compiler/i386/cpupara.pas index ee54aa705d..8768b11875 100644 --- a/compiler/i386/cpupara.pas +++ b/compiler/i386/cpupara.pas @@ -40,6 +40,7 @@ unit cpupara; function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override; function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override; function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override; + procedure get_para_regoff(proccalloption: tproccalloption; paraloc: pcgparalocation; out reg: Byte; out off: LongInt);override; function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override; function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override; procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);override; @@ -285,6 +286,29 @@ unit cpupara; result:=[0..first_mm_imreg-1]; end; + procedure tcpuparamanager.get_para_regoff(proccalloption: tproccalloption; paraloc: pcgparalocation; out reg: Byte; out off: LongInt); + var + I : SizeInt; + begin + with paraloc^ do + case loc of + LOC_REGISTER: + begin + for I := 0 to high(parasupregs) do + if getsupreg(register)=parasupregs[I] then + begin + reg:=I; + break; + end; + off:=0; + end; + LOC_REFERENCE: + begin + reg:=255; + off:=reference.offset; + end; + end; + end; function tcpuparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): TCGPara; var diff --git a/compiler/ncgrtti.pas b/compiler/ncgrtti.pas index 56cf6f022e..5c15ffa830 100644 --- a/compiler/ncgrtti.pas +++ b/compiler/ncgrtti.pas @@ -28,7 +28,7 @@ interface uses cclasses,constexp, aasmbase,aasmcnst, - symbase,symconst,symtype,symdef; + symbase,symconst,symtype,symdef,symsym; type @@ -49,6 +49,8 @@ interface procedure published_write_rtti(st:tsymtable;rt:trttitype); function published_properties_count(st:tsymtable):longint; procedure published_properties_write_rtti_data(tcb: ttai_typedconstbuilder; propnamelist: TFPHashObjectList; st: tsymtable); + procedure write_param_flag(tcb: ttai_typedconstbuilder; parasym:tparavarsym); + procedure methods_write_rtti(tcb: ttai_typedconstbuilder; st:tsymtable); procedure collect_propnamelist(propnamelist:TFPHashObjectList;objdef:tobjectdef); function ref_rtti(def:tdef;rt:trttitype):tasmsymbol; procedure write_rtti_name(tcb: ttai_typedconstbuilder; def: tdef); @@ -77,10 +79,11 @@ implementation cutils, globals,globtype,verbose,systems, fmodule, procinfo, - symtable,symsym, + symtable, aasmtai,aasmdata, defutil, - wpobase + wpobase, + paramgr ; @@ -91,6 +94,24 @@ implementation symconst.ds_none,symconst.ds_none, symconst.ds_none,symconst.ds_none); + ProcCallOptionToCallConv: array[tproccalloption] of byte = ( + { pocall_none } 0, + { pocall_cdecl } 1, + { pocall_cppdecl } 5, + { pocall_far16 } 6, + { pocall_oldfpccall } 7, + { pocall_internproc } 8, + { pocall_syscall } 9, + { pocall_pascal } 2, + { pocall_register } 0, + { pocall_safecall } 4, + { pocall_stdcall } 3, + { pocall_softfloat } 10, + { pocall_mwpascal } 11, + { pocall_interrupt } 12, + { pocall_hardfloat } 13 + ); + type TPropNameListItem = class(TFPHashObject) propindex : longint; @@ -506,9 +527,117 @@ implementation tcb.end_anonymous_record; end; + procedure TRTTIWriter.write_param_flag(tcb: ttai_typedconstbuilder; parasym:tparavarsym); + var + paraspec : byte; + begin + case parasym.varspez of + vs_value : paraspec := 0; + vs_const : paraspec := pfConst; + vs_var : paraspec := pfVar; + vs_out : paraspec := pfOut; + vs_constref: paraspec := pfConstRef; + else + internalerror(2013112904); + end; + { Kylix also seems to always add both pfArray and pfReference + in this case + } + if is_open_array(parasym.vardef) then + paraspec:=paraspec or pfArray or pfReference; + { and these for classes and interfaces (maybe because they + are themselves addresses?) + } + if is_class_or_interface(parasym.vardef) then + paraspec:=paraspec or pfAddress; + { set bits run from the highest to the lowest bit on + big endian systems + } + if (target_info.endian = endian_big) then + paraspec:=reverse_byte(paraspec); + { write flags for current parameter } + tcb.emit_ord_const(paraspec,u8inttype); + end; + + procedure TRTTIWriter.methods_write_rtti(tcb: ttai_typedconstbuilder; st: tsymtable); + var + count: Word; + i,j,k: LongInt; - procedure TRTTIWriter.write_rtti_data(tcb: ttai_typedconstbuilder; def: tdef; rt: trttitype); + sym : tprocsym; + def : tabstractprocdef; + para : tparavarsym; + + reg: Byte; + off: LongInt; + begin + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + + count:=0; + for i:=0 to st.SymList.Count-1 do + if (tsym(st.SymList[i]).typ=procsym) then + inc(count, tprocsym(st.SymList[i]).ProcdefList.count); + + tcb.emit_ord_const(count,u16inttype); + tcb.emit_ord_const(count,u16inttype); + + for i:=0 to st.SymList.Count-1 do + if (tsym(st.SymList[i]).typ=procsym) then + begin + sym:=tprocsym(st.SymList[i]); + for j:=0 to sym.ProcdefList.count-1 do + begin + def:=tabstractprocdef(sym.ProcdefList[j]); + def.init_paraloc_info(callerside); + + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + + tcb.emit_shortstring_const(sym.realname); + tcb.emit_ord_const(3,u8inttype); + tcb.emit_ord_const(ProcCallOptionToCallConv[def.proccalloption],u8inttype); + write_rtti_reference(tcb,def.returndef,fullrtti); + tcb.emit_ord_const(def.callerargareasize,u16inttype); + tcb.emit_ord_const(def.maxparacount + 1,u8inttype); + + for k:=0 to def.paras.count-1 do + begin + para:=tparavarsym(def.paras[k]); + if (vo_is_hidden_para in para.varoptions) and not (vo_is_self in para.varoptions) then + continue; + + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + + { write flags for current parameter } + write_param_flag(tcb, para); + { write param type } + write_rtti_reference(tcb,para.vardef,fullrtti); + + paramanager.get_para_regoff(def.proccalloption, para.paraloc[callerside].location,reg,off); + + tcb.emit_ord_const(reg,u8inttype); + tcb.emit_ord_const(off,u32inttype); + + { write name of current parameter } + tcb.emit_shortstring_const(para.realname); + + tcb.end_anonymous_record; + end; + + tcb.end_anonymous_record; + end; + end; + tcb.end_anonymous_record; + end; + + + procedure TRTTIWriter.write_rtti_data(tcb: ttai_typedconstbuilder; def: tdef; rt: trttitype); procedure unknown_rtti(def:tstoreddef); begin tcb.emit_ord_const(tkUnknown,u8inttype); @@ -855,56 +984,6 @@ implementation procedure procvardef_rtti(def:tprocvardef); - const - ProcCallOptionToCallConv: array[tproccalloption] of byte = ( - { pocall_none } 0, - { pocall_cdecl } 1, - { pocall_cppdecl } 5, - { pocall_far16 } 6, - { pocall_oldfpccall } 7, - { pocall_internproc } 8, - { pocall_syscall } 9, - { pocall_pascal } 2, - { pocall_register } 0, - { pocall_safecall } 4, - { pocall_stdcall } 3, - { pocall_softfloat } 10, - { pocall_mwpascal } 11, - { pocall_interrupt } 12, - { pocall_hardfloat } 13 - ); - - procedure write_param_flag(parasym:tparavarsym); - var - paraspec : byte; - begin - case parasym.varspez of - vs_value : paraspec := 0; - vs_const : paraspec := pfConst; - vs_var : paraspec := pfVar; - vs_out : paraspec := pfOut; - vs_constref: paraspec := pfConstRef; - else - internalerror(2013112904); - end; - { Kylix also seems to always add both pfArray and pfReference - in this case - } - if is_open_array(parasym.vardef) then - paraspec:=paraspec or pfArray or pfReference; - { and these for classes and interfaces (maybe because they - are themselves addresses?) - } - if is_class_or_interface(parasym.vardef) then - paraspec:=paraspec or pfAddress; - { set bits run from the highest to the lowest bit on - big endian systems - } - if (target_info.endian = endian_big) then - paraspec:=reverse_byte(paraspec); - { write flags for current parameter } - tcb.emit_ord_const(paraspec,u8inttype); - end; procedure write_para(parasym:tparavarsym); begin @@ -912,7 +991,7 @@ implementation if not(vo_is_hidden_para in parasym.varoptions) then begin { write flags for current parameter } - write_param_flag(parasym); + write_param_flag(tcb, parasym); { write name of current parameter } tcb.emit_shortstring_const(parasym.realname); { write name of type of current parameter } @@ -932,7 +1011,7 @@ implementation targetinfos[target_info.system]^.alignment.recordalignmin, targetinfos[target_info.system]^.alignment.maxCrecordalign); { write flags for current parameter } - write_param_flag(parasym); + write_param_flag(tcb,parasym); { write param type } write_rtti_reference(tcb,parasym.vardef,fullrtti); { write name of current parameter } @@ -1134,6 +1213,9 @@ implementation { write published properties for this object } published_properties_write_rtti_data(tcb,propnamelist,def.symtable); + { write methods for this object } + methods_write_rtti(tcb, def.symtable); + tcb.end_anonymous_record; tcb.end_anonymous_record; @@ -1477,6 +1559,8 @@ implementation end; procedure TRTTIWriter.write_child_rtti_data(def:tdef;rt:trttitype); + var + i,j: SizeInt; begin case def.typ of enumdef : @@ -1498,7 +1582,20 @@ implementation if (rt=initrtti) or (tobjectdef(def).objecttype=odt_object) then fields_write_rtti(tobjectdef(def).symtable,rt) else - published_write_rtti(tobjectdef(def).symtable,rt); + begin + published_write_rtti(tobjectdef(def).symtable,rt); + + if is_any_interface_kind(def) then + with tobjectdef(def).symtable do + for i := 0 to SymList.Count-1 do + if (tsym(SymList[i]).typ=procsym) then + with tprocsym(tobjectdef(def).symtable.SymList[i]) do + for j := 0 to ProcdefList.Count - 1 do + begin + write_rtti(tabstractprocdef(ProcdefList[j]).returndef,rt); + params_write_rtti(tabstractprocdef(ProcdefList[j]),rt); + end; + end; end; classrefdef, pointerdef: diff --git a/compiler/options.pas b/compiler/options.pas index bbaca528aa..e79be6404a 100644 --- a/compiler/options.pas +++ b/compiler/options.pas @@ -3308,6 +3308,7 @@ begin def_system_macro('FPC_HAS_INTERNAL_ABS_INT64'); {$endif x86_64 or powerpc64 or aarch64} + def_system_macro('FPC_HAS_EXTENDEDINTERFACERTTI'); def_system_macro('FPC_HAS_UNICODESTRING'); def_system_macro('FPC_RTTI_PACKSET1'); def_system_macro('FPC_HAS_CPSTRING'); diff --git a/compiler/paramgr.pas b/compiler/paramgr.pas index fa60dba607..39e27c3c38 100644 --- a/compiler/paramgr.pas +++ b/compiler/paramgr.pas @@ -81,6 +81,8 @@ unit paramgr; function get_volatile_registers_flags(calloption : tproccalloption):tcpuregisterset;virtual; function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;virtual; + procedure get_para_regoff(proccalloption: tproccalloption; paraloc: pcgparalocation; out reg: Byte; out off: LongInt);virtual; + procedure getintparaloc(list: TAsmList; pd: tabstractprocdef; nr : longint; var cgpara: tcgpara);virtual; {# allocate an individual pcgparalocation that's part of a tcgpara @@ -278,6 +280,12 @@ implementation result:=[]; end; + procedure tparamanager.get_para_regoff(proccalloption: tproccalloption; paraloc: pcgparalocation; out reg: Byte; out off: LongInt); + begin + reg:=0; + off:=0; + end; + {$if first_mm_imreg = 0} {$WARN 4044 OFF} { Comparison might be always false ... } {$endif} diff --git a/compiler/x86_64/cpupara.pas b/compiler/x86_64/cpupara.pas index 4b99b40800..0a13b337f4 100644 --- a/compiler/x86_64/cpupara.pas +++ b/compiler/x86_64/cpupara.pas @@ -44,6 +44,7 @@ unit cpupara; function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override; function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override; function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override; + procedure get_para_regoff(proccalloption: tproccalloption; paraloc: pcgparalocation; out reg: Byte; out off: LongInt);override; function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override; function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override; function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override; @@ -906,13 +907,71 @@ unit cpupara; result:=[RS_XMM0..RS_XMM15]; end; - function tcpuparamanager.get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset; begin result:=[RS_ST0..RS_ST7]; end; + procedure tcpuparamanager.get_para_regoff(proccalloption: tproccalloption; paraloc: pcgparalocation; out reg: Byte; out off: LongInt); + var + I : SizeInt; + begin + with paraloc^ do + case loc of + LOC_REGISTER: + begin + reg:=getsupreg(register); + { winx64 uses different registers } + if target_info.system=system_x86_64_win64 then + begin + for I := 0 to high(paraintsupregs_winx64) do + if reg=paraintsupregs_winx64[I] then + begin + reg:=I; + break; + end; + end + else + for I := 0 to high(paraintsupregs) do + if reg=paraintsupregs[I] then + begin + reg:=I; + break; + end; + off:=0; + end; + LOC_MMREGISTER: + begin + reg:=getsupreg(register); + { winx64 uses different registers } + if target_info.system=system_x86_64_win64 then + begin + for I := 0 to high(parammsupregs_winx64) do + if reg=parammsupregs_winx64[I] then + begin + reg:=I; + break; + end; + end + else + for I := 0 to high(parammsupregs) do + if reg=parammsupregs[I] then + begin + reg:=I; + break; + end; + off:=0; + end; + LOC_REFERENCE: + begin + reg:=255; + off:=reference.offset; + end; + end; + end; + + function tcpuparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara; const intretregs: array[0..1] of tregister = (NR_FUNCTION_RETURN_REG,NR_FUNCTION_RETURN_REG_HIGH); diff --git a/rtl/objpas/typinfo.pp b/rtl/objpas/typinfo.pp index 2168030e78..ff1bf734b7 100644 --- a/rtl/objpas/typinfo.pp +++ b/rtl/objpas/typinfo.pp @@ -52,9 +52,9 @@ unit typinfo; TFloatType = (ftSingle,ftDouble,ftExtended,ftComp,ftCurr); {$endif} TMethodKind = (mkProcedure,mkFunction,mkConstructor,mkDestructor, - mkClassProcedure,mkClassFunction,mkClassConstructor, + mkClassProcedure,mkClassFunction,mkClassConstructor, mkClassDestructor,mkOperatorOverload); - TParamFlag = (pfVar,pfConst,pfArray,pfAddress,pfReference,pfOut); + TParamFlag = (pfVar,pfConst,pfArray,pfAddress,pfReference,pfOut,pfConstRef); TParamFlags = set of TParamFlag; TIntfFlag = (ifHasGuid,ifDispInterface,ifDispatch,ifHasStrGUID); TIntfFlags = set of TIntfFlag; @@ -63,6 +63,7 @@ unit typinfo; // don't rely on integer values of TCallConv since it includes all conventions // which both delphi and fpc support. In the future delphi can support more and // fpc own conventions will be shifted/reordered accordinly + PCallConv = ^TCallConv; TCallConv = (ccReg, ccCdecl, ccPascal, ccStdCall, ccSafeCall, ccCppdecl, ccFar16, ccOldFPCCall, ccInternProc, ccSysCall, ccSoftFloat, ccMWPascal); @@ -161,6 +162,49 @@ unit typinfo; function GetParam(ParamIndex: Integer): PProcedureParam; end; + PVmtMethodParam = ^TVmtMethodParam; + TVmtMethodParam = + {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} + packed + {$endif FPC_REQUIRES_PROPER_ALIGNMENT} + record + Flags: TParamFlags; + ParamType: PTypeInfo; + ParReg: Byte; + ParOff: LongInt; + Name: ShortString; + {Attribute data TODO} + end; + + PIntfMethodEntry = ^TIntfMethodEntry; + TIntfMethodEntry = + {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} + packed + {$endif FPC_REQUIRES_PROPER_ALIGNMENT} + record + Name: ShortString; + { + Version: Byte; + CC: TCallConv; + ResultType: PTypeInfo; + StackSize: Word; + ParamCount: Byte; + Params: array[0..ParamCount - 1] of TVmtMethodParam; + } + {Attribute data TODO} + end; + + PIntfMethodTable = ^TIntfMethodTable; + TIntfMethodTable = + {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} + packed + {$endif FPC_REQUIRES_PROPER_ALIGNMENT} + record + Count: Word; + RTTICount: Word;//$FFFF if there is no further info, or the value of Count + {Entry: array[0..Count - 1] of TIntfMethodEntry} + end; + PTypeData = ^TTypeData; TTypeData = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} @@ -241,7 +285,11 @@ unit typinfo; IntfFlags : TIntfFlagsBase; GUID: TGUID; IntfUnit: ShortString; - { here the properties follow as Word Count & array of TPropInfo } + { + IntfPropCount: Word; + IntfProps: array[0..IntfPropCount-1] of TPropInfo; + IntfMethTable : TIntfMethodTable; + } ); tkInterfaceRaw: ( @@ -250,7 +298,11 @@ unit typinfo; IID: TGUID; RawIntfUnit: ShortString; IIDStr: ShortString; - { here the properties follow as Word Count & array of TPropInfo } + { + RawIntfPropCount: Word; + RawIntfProps: array[0..IntfPropCount-1] of TPropInfo; + IntfMethTable : TIntfMethodTable; + } ); tkArray: (ArrayData: TArrayTypeData); @@ -403,10 +455,7 @@ Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Function GetPropValue(Instance: TObject; const PropName: string): Variant; Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant; -Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant; -Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant; Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant); -Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant); Function GetVariantProp(Instance: TObject; PropInfo : PPropInfo): Variant; Function GetVariantProp(Instance: TObject; const PropName: string): Variant; Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant); @@ -439,8 +488,8 @@ const Type EPropertyError = Class(Exception); - TGetPropValue = Function (Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean) : Variant; - TSetPropValue = Procedure (Instance: TObject; PropInfo: PPropInfo; const Value: Variant); + TGetPropValue = Function (Instance: TObject; const PropName: string; PreferStrings: Boolean) : Variant; + TSetPropValue = Procedure (Instance: TObject; const PropName: string; const Value: Variant); TGetVariantProp = Function (Instance: TObject; PropInfo : PPropInfo): Variant; TSetVariantProp = Procedure (Instance: TObject; PropInfo : PPropInfo; const Value: Variant); @@ -1994,38 +2043,22 @@ end; Function GetPropValue(Instance: TObject; const PropName: string): Variant; begin - Result := GetPropValue(Instance,FindPropInfo(Instance, PropName)); -end; - -Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant; - -begin - Result := GetPropValue(Instance,FindPropInfo(Instance, PropName),PreferStrings); + Result:=GetPropValue(Instance,PropName,True); end; -Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant; -begin - Result := GetPropValue(Instance, PropInfo, True); -end; -Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant; +Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant; begin CheckVariantEvent(CodePointer(OnGetPropValue)); - Result:=OnGetPropValue(Instance,PropInfo,PreferStrings); + Result:=OnGetPropValue(Instance,PropName,PreferStrings) end; Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant); begin - SetPropValue(Instance, FindPropInfo(Instance, PropName), Value); -end; - -Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant); - -begin CheckVariantEvent(CodePointer(OnSetPropValue)); - OnSetPropValue(Instance,PropInfo,Value); + OnSetPropValue(Instance,PropName,Value); end; |