Re: [fpc-devel] (ref types / circles) Re: Defer keyword
Am 10.05.2021 um 23:18 schrieb Ryan Joseph via fpc-devel: On May 10, 2021, at 3:05 PM, Sven Barth via fpc-devel wrote: Why should they? You pass the reference to a non-reference counted parameter/field/variable, the reference count is increased and then what? It sits there for the remaining life time of the program, because nothing decrements the reference count? I see what you mean. The FGL containers also call Finalize though when the container is freed so it does indeed keep balanced. But only if the generic container is indeed specialized with the refcounted type. If it's e.g. TObject then the whole thing is up in the air again, because the whole point is that we *don't* want to burden non-reference counted class types with the reference counting stuff (and the need to check at runtime whether the type is reference counted or not *is* a burden). Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Defer keyword
On 5/11/2021 4:09 AM, Ryan Joseph via fpc-devel wrote: On May 10, 2021, at 5:59 PM, Kostas Michalopoulos via fpc-devel wrote: You do not need any special language feature for that, you can simply do something like ReleaseLater(TObject.Create) yes but we can't get back the reference. It's a small thing but making this possible as return type means we can chain the calls together and make it a one line statement. It's just a nice thing from Objective-C which we use heavily to manage memory and it works very well. How about function ReleaseLater(Obj: TObject): TObject that simply returns Obj? (though TBH i can't say i am a fan of these chains from a readability perspective). Kostas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Google APIs - Authenticate using a service account?
On Tue, Jun 30, 2020 at 12:47 AM Michael Van Canneyt wrote: > > The problem with the service account is that you must create a JWT Token. > FPC does not yet have a unit that can generate *and sign* a JWT Token. > > The good news is I have this weekend a reminder that I received some code > that will allow me to complete the JWT Token support in FPC using at > least the RSA256 signing algorithm (and some others as well). Hi Michael. I would like to assist with this if possible. According to rfc7519: https://datatracker.ietf.org/doc/html/rfc7519#section-8 The *required* JWT Signature and MAC algorithms are: HS256 (HMAC SHA-256) none The *recommended* JWT Signature and MAC algorithms are: RS256 (RSASSA-PKCS1-v1_5 with the SHA-256 hash) ES256 (ECDSA using the P-256 curve and the SHA-256 hash) The Google API supports the following signing algorithms: https://cloud.google.com/iot/docs/how-tos/credentials/jwts JWT RS256 (RSASSA-PKCS1-v1_5 using SHA-256 RFC 7518 sec 3.3). This is expressed as RS256 in the alg field in the JWT header. JWT ES256 (ECDSA using P-256 and SHA-256 RFC 7518 sec 3.4), defined in OpenSSL as the prime256v1 curve. This is expressed as ES256 in the alg field in the JWT header. So for google api, we need at least RS256 (RSASSA-PKCS1-v1_5 using SHA-256). Adding signing directly to fpjwt.pp would be the cleanest, but you need to add native crypto code to fpc for that. https://svn.freepascal.org/svn/fpc/trunk/packages/fcl-web/src/base/fpjwt.pp There are libraries that have it: https://github.com/fundamentalslib/fundamentals5 https://github.com/Xor-el/CryptoLib4Pascal Adding JWT signing to google API units could be done with OpenSSL and it is already a dependency. OpenSSL can sign and verify a JWT using both RS256 and ES256. Examples: https://stackoverflow.com/questions/58313106/create-rs256-jwt-in-bash https://stackoverflow.com/questions/40559765/how-to-verify-json-web-tokens-with-openssl https://learn.akamai.com/en-us/webhelp/iot/jwt-access-control/GUID-054028C7-1BF8-41A5-BD2E-A3E00F6CA550.html What do you think? ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Defer keyword
> On May 10, 2021, at 5:59 PM, Kostas Michalopoulos via fpc-devel > wrote: > > You do not need any special language feature for that, you can simply do > something like > >ReleaseLater(TObject.Create) yes but we can't get back the reference. It's a small thing but making this possible as return type means we can chain the calls together and make it a one line statement. It's just a nice thing from Objective-C which we use heavily to manage memory and it works very well. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Defer keyword
On 5/8/2021 8:27 PM, Ryan Joseph via fpc-devel wrote: That was a bad example. It's for ANY class really. o := TObject.Create.AutoRelease; Then next event cycle the autorelease pool frees all the objects added to it. Very simple but effective however we can't do this in Pascal without a new permissive return type. You do not need any special language feature for that, you can simply do something like ReleaseLater(TObject.Create) and have ReleaseLater and ReleaseQueuedObjects procedures in a shared unit like procedure ReleaseLater(Obj: TObject); procedure ReleaseQueuedObjects; and have ReleaseQueuedObjects called on app idle. LCL already has something like that with TApplication.ReleaseComponent but, as the name implies, it is only for TComponent instances. However nothing prevents you from making your own, it is just a few lines of code and certainly an app with flow complex enough to need such a construct wont be bothered by a few additional lines for this. You could even use type helpers to make it look like a method :-P. Kostas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] (ref types / circles) Re: Defer keyword
> On May 10, 2021, at 3:05 PM, Sven Barth via fpc-devel > wrote: > > Why should they? You pass the reference to a non-reference counted > parameter/field/variable, the reference count is increased and then what? It > sits there for the remaining life time of the program, because nothing > decrements the reference count? I see what you mean. The FGL containers also call Finalize though when the container is freed so it does indeed keep balanced. Lets focus on the record approach for now then. I don't think I know enough to understand where are the pitfalls are. > You should reread the visibility rules of Object Pascal: > - private: identifier is visible inside the whole unit > - strict private: identifier is only visible inside code of the class > - protected: identifier is visible inside the whole unit as well as inside > descendants of the class as well as type helpers > - strict protected: identifier is visible inside code of the class, inside > descendants of the class as well as type helpers > - public: identifier is visible in the whole unit and (if it's declared in > the interface section) any unit that includes that unit > - published: like public, but with RTTI data yes, yes, I know. I thought we'd do something different. > >> Some things: >> >> 1) What do read/write access even mean in the context of the default >> properties? The terms don't really make much sense given what the the >> property does. Right now the property could be read only or write only but >> those don't really have any affect on the hoisting process itself so it's >> kind of deceptive. Methods are always "read-only" but i guess you could >> hoist fields/properties and inherit the access level of the default >> property. No idea if that's helpful or just adding needless complexity. Any >> ideas? > Property accessors indeed don't really make sense. Maybe a "default field" > would be better than a "default property". "Default field" is certainly more unique and thus better. We'll have to think about this more. > >> 2) I also think there needs to be another name for the feature than "default >> property" since this term is already used for array indexers and could even >> be used for something like traits in the future (traits would be reusing >> much of this code). I need to add some enum names and default_property is >> already used so I need to think of something else. >> >> 3) What about allowing type pointers as default properties? This should be >> possible and is in the spirit of the feature anyways, that is ref counting. >> We may need to add some additional logic to properties (just internally) so >> that they can be used with pointers but I'm not sure about that yet. > Pointers are only useful if the ^ "operator" is hoisted as well. I meant to say pointers to records so yes the ^. would need to be there. I haven't looked into how this would be implemented but I got it working with classes for now. It would be nice to make pointers to records be possible for smart pointers so I'll look into that later. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] (ref types / circles) Re: Defer keyword
Am 09.05.2021 um 17:14 schrieb Ryan Joseph via fpc-devel: On May 9, 2021, at 3:40 AM, Sven Barth wrote: === code begin === {$mode objfpc} type TTest = class protected procedure DoSomething; end; TTestSub = class refcounted(TTest) public procedure Test; end; procedure TTest.DoSomething; begin // maybe this functions stores the reference SomeFuncThatTakesAObject(Self); end; procedure TTest.Test; begin DoSomething; end; === code end === I see, the reference counting is broken because you move up into a non-ref counted class. Yeah that's something programers simply should not do or be prevented from doing. I don't see this particular case being a problem however because your ref counted object is going to be in the base of a hierarchy, probably enforced even. The only reason for opt-in ARC is so we don't pollute TObject but it still doesn't mean that you should be adding this in the middle of class trees. But that won't stop users from introducing reference counted classes somewhere down in the tree. Enabling reference counting by type is essentially introducing a new class hierarchy and that makes it useless for interacting with the existing RTL/FCL/LCL. Here is the bigger problem: var list: TObjectList; procedure HandleObject(obj: TObject); begin // the list now stores the class but it's lost ref-counting because it was cast to TObject list.Add(obj); end; var obj: TTestSub; begin HandleObject(obj); end; or var obj: TObject; begin // we lost ref counting now! obj := TTestSub.Create; HandleObject(obj); end; Once you cast away from your managed class type things fall apart. Records aid this by not allowing casting but you could enforce some kinds of checks for managed classes if you wanted to. Doesn't seem like a deal breaker to me if you add new type rules for passing/assigning. That is exactly *the same* problem, not a "bigger" one. It doesn't matter if the instance is passed to a function right away or through using Self in a parent class, the result is the same: the reference count is no longer accurate. And *that* is why I'm in favor of an approach that is external to the class. It's much clearer then that this is not something inherent to the class and thus users won't expect this to be handled transparently (and this is also why I'm against a keyword like Michael suggested, it only wakes expectations that we won't and can't fullfill). Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] (ref types / circles) Re: Defer keyword
Am 09.05.2021 um 16:58 schrieb Ryan Joseph via fpc-devel: On May 9, 2021, at 3:40 AM, Sven Barth wrote: It seems that you don't work much with classes then. If one disallows the assignment of a reference counted class to a non-reference counted one then you can't use e.g. TStringList.Objects. There is also the problem of method pointers, which essentially only have a Pointer as Self data. Also a reference might escape in a parent class (for this example I'll use the syntax I used in my branch): I use classes all the time but I thought that any assignments or passing to function args call the management operators. So if you pass a managed class to a TStringList.Add for example then AddRef will indeed by called. You're saying this isn't the case? I know the FGL classes can work with ref counted objects so why is it any different if a class type was managed and then passed into one of these types? Why should they? You pass the reference to a non-reference counted parameter/field/variable, the reference count is increased and then what? It sits there for the remaining life time of the program, because nothing decrements the reference count? Anyways I wrote up a little wiki with some potential implementation notes about a default property (which overlaps on the "defaults implements" as traits stuff). Important points are restricting what types can be default properties (classes and maybe/probably typed pointers) and limiting hoisting to subscripting, so it's kind of like the -> operator overload in C++. https://github.com/genericptr/freepascal/wiki/Default-property It shouldn't hoist only public members, it should hoist according to the visibility rules (thus the hoisting depends on the callsite), otherwise it won't behave like Pascal classes do and thus we can forget it right away. So this means if the property is in the private section it looks at private visibility in the parent class? Yeah that's probably right we need to do that. You should reread the visibility rules of Object Pascal: - private: identifier is visible inside the whole unit - strict private: identifier is only visible inside code of the class - protected: identifier is visible inside the whole unit as well as inside descendants of the class as well as type helpers - strict protected: identifier is visible inside code of the class, inside descendants of the class as well as type helpers - public: identifier is visible in the whole unit and (if it's declared in the interface section) any unit that includes that unit - published: like public, but with RTTI data Some things: 1) What do read/write access even mean in the context of the default properties? The terms don't really make much sense given what the the property does. Right now the property could be read only or write only but those don't really have any affect on the hoisting process itself so it's kind of deceptive. Methods are always "read-only" but i guess you could hoist fields/properties and inherit the access level of the default property. No idea if that's helpful or just adding needless complexity. Any ideas? Property accessors indeed don't really make sense. Maybe a "default field" would be better than a "default property". 2) I also think there needs to be another name for the feature than "default property" since this term is already used for array indexers and could even be used for something like traits in the future (traits would be reusing much of this code). I need to add some enum names and default_property is already used so I need to think of something else. 3) What about allowing type pointers as default properties? This should be possible and is in the spirit of the feature anyways, that is ref counting. We may need to add some additional logic to properties (just internally) so that they can be used with pointers but I'm not sure about that yet. Pointers are only useful if the ^ "operator" is hoisted as well. Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] (ref types / circles) Re: Defer keyword
Over the weekend I fixed up my old default property code to work with records only which implement classes (which reduced lots of the complexity). It's actually a pretty clean and small implementation so I put a patch you can look at and try. It's not decided upon but this is a place to start should we decide to go this route for "start pointers". https://bugs.freepascal.org/view.php?id=38872 Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel