[fpc-devel] Lazarus server maintenance

2021-12-23 Thread Marc Weustink via fpc-devel

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

2021-12-23 Thread Blaise--- via fpc-devel

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...

2021-12-23 Thread Ozz Nixon via fpc-devel
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

2021-12-23 Thread Blaise--- via fpc-devel

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

2021-12-23 Thread Blaise--- via fpc-devel

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

2021-12-23 Thread Blaise--- via fpc-devel

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

2021-12-23 Thread Ryan Joseph via fpc-devel
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