[fpc-devel] Lazarus server maintenance
Hi, On Monday 27 December 9.00 CET (8.00 GMT) the Lazarus server will be down for maintenance. This affects the following services: * Lazarus website * Lazarus mailinglists * Lazarus online package manager * Lazarus and FreePascal forum Thanks, Marc ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] Initialising method pointers with class methods
DCC allows the subj (provided that the class type is known at compile time), FPC does not. The attached init_methptr_with_classmeth.patch implements this feature. ---8<--- type C = class class procedure Foo; end; class procedure C.Foo; begin end; type CC = class of C; type H = class helper for C end; type T = procedure of object; //var aC: C = nil; //var aCC: CC = nil; // Still rejected: //var ViaInstance: T = aC.Foo; //var ViaClassRef: T = aCC.Foo; const ViaClass: T = C.Foo; // NB: This needs metaclass_meth_to_procvar-2.patch // from https://lists.freepascal.org/pipermail/fpc-devel/2021-December/044249.html // Otherwise: AV in FPC var ViaMetaclass: T = CC.Foo; // TODO: Currently, ICE 2021122302 -- needs to be fixed elsewhere. // See https://lists.freepascal.org/pipermail/fpc-devel/2021-December/044251.html //var ViaHelper: T = H.Foo; procedure Report(const s: string; const X: T); var Status: Boolean; begin Status := (TMethod(X).Code = @C.Foo) and (TMethod(X).Data = Pointer(C)); writeln(s, ': ', Status) end; begin Report('via class', ViaClass); Report('via metaclass', ViaMetaclass) end. ---8<--- Proposed new error message for parser_e_no_procvarobj_const: Cannot initialize a method pointer: Self pointer is not known at compile time In order to initialize a method pointer with a method, the value of the Self pointer for calling that method at run time must be known at compile time. Thus, a method pointer can be initialized either with NIL, or with a class method that is accessed via a class type or a class reference type. -- βþ # HG changeset patch # User Blaise.ru # Date 1640264248 -10800 # Thu Dec 23 15:57:28 2021 +0300 + allow initialisation of method pointers with class methods (when class types are known at compile time) diff -r d8747975e106 -r e77bf4543d51 ngtcon.pas --- a/ngtcon.pasWed Dec 22 08:12:51 2021 +0300 +++ b/ngtcon.pasThu Dec 23 15:57:28 2021 +0300 @@ -1455,6 +1455,8 @@ procaddrdef: tprocvardef; havepd, haveblock: boolean; +selfnode: tnode; +selfdef: tdef; begin { Procvars and pointers are no longer compatible. } { under tp: =nil or =var under fpc: =nil or =@var } @@ -1469,12 +1471,6 @@ ftcb.maybe_end_aggregate(def); exit; end; -{ you can't assign a value other than NIL to a typed constant } -{ which is a "procedure of object", because this also requires } -{ address of an object/class instance, which is not known at } -{ compile time (JM)} -if (po_methodpointer in def.procoptions) then - Message(parser_e_no_procvarobj_const); { parse the rest too, so we can continue with error checking } getprocvardef:=def; n:=comp_expr([ef_accept_equal]); @@ -1540,10 +1536,35 @@ begin ftcb.queue_emit_staticvar(tstaticvarsym(tloadnode(n).symtableentry)); end; +{ the Data field of a method pointer can be initialised + either with NIL (handled above) or with a class type } +if po_methodpointer in def.procoptions then + begin +selfnode:=tloadnode(n).left; +{ TODO: Happens for helpers. Needs to be fixed elsewhere. + See https://lists.freepascal.org/pipermail/fpc-devel/2021-December/044251.html } +if selfnode = nil then + internalerror(2021122302); +{ class type must be known at compile time } +if (selfnode.nodetype=loadvmtaddrn) + and (tloadvmtaddrnode(selfnode).left.nodetype=typen) +then + begin +selfdef:=selfnode.resultdef; +if selfdef.typ<>classrefdef then + internalerror(2021122301); +selfdef:=tclassrefdef(selfdef).pointeddef; +ftcb.emit_tai(Tai_const.Create_sym( + current_asmdata.RefAsmSymbol(tobjectdef(selfdef).vmt_mangledname,AT_DATA)), + def); + end +else + Message(parser_e_no_procvarobj_const); + end { nested procvar typed consts can only be initialised with nil (checked above) or with a global procedure (checked here), because in other cases we need a valid frame pointer } -if is_nested_pd(def) then +else if is_nested_pd(def) then begin if haveblock or is_nested_pd(pd) then ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] Just wanted to share...
As some of you who know me, know I wrote all kinds of interpreter and pcode compilers. Last night I decided to compile my latest engine in delphi. I ran a script that does over 18 million double = double + 0.5 Fpc build takes 1m 26.8s Delphi takes over 15min... I have up and walked away, when I came back after it had been 30min it had finished. Good work guys!! Delphi exe was about 100k smaller, but fpc smacked delphi around like a Lil B!!! On Thu, Dec 23, 2021, 6:16 AM Ryan Joseph via fpc-devel < fpc-devel@lists.freepascal.org> wrote: > Thank you for continuing work on this, we all really appreciate your > efforts. > > > On Dec 23, 2021, at 1:16 AM, Blaise--- via fpc-devel < > fpc-devel@lists.freepascal.org> wrote: > > > > 1) The attached metaclass_meth_to_procvar-1.patch fixes the internal > error reported for: > > Regards, > Ryan Joseph > > ___ > fpc-devel maillist - fpc-devel@lists.freepascal.org > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel > ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] Assigning class methods, accessed via an object or helper type, to incompatible procvars
On 22.12.2021 21:16, Blaise wrote: 1) The attached metaclass_meth_to_procvar-1.patch fixes the internal error reported for: [ICE] Assigning class methods, accessed via a class reference type, to incompatible procvars Also fixes: 1B) [ICE] Assigning class static methods, accessed via an object type, to incompatible procvars ---8<--- type O = object class procedure Static; static; end; class procedure O.Static; begin end; var IncompatWStatic: procedure of object; begin IncompatWStatic := O.Static // ICE 200301042 end. ---8<--- 1C) [ICE] Assigning class methods, accessed via a helper type, to incompatible procvars ---8<--- type C = class end; type H = class helper for C class procedure NonStatic; class procedure Static; static; end; class procedure H.NonStatic; begin end; class procedure H.Static; begin end; var IncompatWNonStatic: procedure; var IncompatWStatic: procedure of object; begin IncompatWNonStatic := H.NonStatic; // ICE 200301042 IncompatWStatic := H.Static // ICE 200301042 end. ---8<--- See https://lists.freepascal.org/pipermail/fpc-devel/2021-December/044251.html for the discussion on rejecting such qualification. -- βþ ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] Assigning instance methods, accessed via a type, to method pointers
Subj silently produces invalid codegen: ---8<--- var Z: procedure of object; type R = record procedure Foo; end; procedure R.Foo; begin end; type O = object procedure Foo; end; procedure O.Foo; begin end; type C = class procedure Foo; class procedure ClassCtx; end; procedure C.Foo; begin end; class procedure C.ClassCtx; begin Z := Foo; // BadCG: .Code = C.Foo; .Data = C end; type CC = class of C; var aCC: CC = nil; type H = class helper for C procedure Bar; class procedure ClassCtx2; end; procedure H.Bar; begin end; class procedure H.ClassCtx2; begin Z := Bar; // BadCG: .Code = H.Bar; .Data = C end; begin Z := R.Foo; // BadCG: GARBAGE Z := O.Foo; // BadCG: GARBAGE Z := C.Foo; // BadCG: .Code = C.Foo; .Data = C Z := CC.Foo; // BadCG: GARBAGE Z := aCC.Foo; // BadCG: .Code = C.Foo; .Data = aCC // Currently allowed, and we get the fix for this for free. // Such qualification may become rejected; // see https://lists.freepascal.org/pipermail/fpc-devel/2021-December/044251.html Z := H.Bar; // BadCG: GARBAGE end. ---8<--- The attached methptr_to_instancemeth_via_type.patch catches all these cases and reports the proper error: Error: Only class methods, class properties and class variables can be referred with class references -- βþ # HG changeset patch # User Blaise.ru # Date 1640264248 -10800 # Thu Dec 23 15:57:28 2021 +0300 ! reject assignments of instance methods, accessed via a type, to method pointers (invalid codegen) diff -r d880e6695537 -r 4fddd039bb22 pexpr.pas --- a/pexpr.pas Mon Dec 20 20:55:22 2021 +0300 +++ b/pexpr.pas Thu Dec 23 15:57:28 2021 +0300 @@ -1361,8 +1361,26 @@ again,p1,callflags,spezcontext); { we need to know which procedure is called } do_typecheckpass(p1); + + { We are loading... } + if p1.nodetype=loadn then + begin + if + { an instance method } + not(po_classmethod in tloadnode(p1).procdef.procoptions) + { into a method pointer (not just taking a code address) } + and not getaddr + { and the selfarg is... } + and( + { either a record/object/helper type, } + not assigned(tloadnode(p1).left) + { or a class/metaclass type, or a class reference } + or{else} (tloadnode(p1).left.resultdef.typ=classrefdef) + ) then + Message(parser_e_only_class_members_via_class_ref); + end { calling using classref? } - if ( + else if ( isclassref or ( (isobjecttype or ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] Assigning class non-static methods, accessed via a helper type, to method pointers
Subj silently produces invalid codegen: ---8<--- type C = class end; type H = class helper for C class procedure Bar; end; class procedure H.Bar; begin writeln('H.Bar(self=', ClassName, ')') end; var Z: procedure of object; begin Z := H.Bar; // BadCG: GARBAGE // H.Bar; // REJECTED end. ---8<--- What is the consensus on: A) fixing the codegen? B) rejecting such access? DCC does reject both statements, but it is not consistent with rejecting such qualifications everywhere. Practically, allowing such qualifications could be useful for selecting a particular method. For example: ---8<--- type H2 = class helper (H) for C class procedure Bar; end; ---8<--- Also, despite the comment in tcallnode.pass_1 saying: CGMessage(parser_e_no_category_as_types); { we get an internal error when trying to insert the hidden parameters in this case } when I comment out the call to CGMessage, I get no ICE for H.Bar only EXTDEBUG warnings: Warning: Expectloc is not set in firstpass: calln Warning: ExpectLoc is not set before secondpass: calln Warning: Location (LOC_VOID) not equal to expectloc (LOC_INVALID): calln and invalid codegen. -- βþ ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Assigning class methods, accessed via a class reference type, to procvars
Thank you for continuing work on this, we all really appreciate your efforts. > On Dec 23, 2021, at 1:16 AM, Blaise--- via fpc-devel > wrote: > > 1) The attached metaclass_meth_to_procvar-1.patch fixes the internal error > reported for: Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel