Re: [fpc-devel] OSX: Setting up parameters to objc_msgSend()
On 10/12/18 8:17 AM, Dmitry Boyarintsev wrote: So, I'm wondering if it's actually a compiler issue or headers issue. and can ByteBool be used as a substitute for signed char. thanks, Dmitry ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel Changing the header for NSMenuItem.setEnable(BOOL) to NSMenuItem(ByteBool) results in the following code in TCocoaWSmenuITem.setEnable: 0x1001ba67e <+70>: movq %rax, %rbx 0x1001ba681 <+73>: movq 0x329ef8(%rip), %rsi ; "setEnabled:" 0x1001ba688 <+80>: movb -0x10(%rbp), %al 0x1001ba68b <+83>: orb %al, %al 0x1001ba68d <+85>: setne %dl 0x1001ba690 <+88>: negb %dl 0x1001ba692 <+90>: movsbl %dl, %edx 0x1001ba695 <+93>: movq %rbx, %rdi 0x1001ba698 <+96>: callq 0x1002d23da ; symbol stub for: objc The movsbl %dl, %edx is good. Unfortunately the value of %edx is 0x not 0x0001. This is the same result I saw when I changed it to LongBool. David ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] OSX: Setting up parameters to objc_msgSend()
Thanks. I'll get a bug report in tomorrow morning. On 10/11/18 3:16 PM, Jonas Maebe wrote: On 11/10/18 21:41, David Jenkins wrote: Here is the assembly code generated by fpc (3.1.1) for just the section where .setEnabled(Enabled) is called -> 0x1001ba68d <+61>: movq -0x8(%rbp), %rdi 0x1001ba691 <+65>: callq 0x1002016d0 ; GETHANDLE at menuitem.inc:515 0x1001ba696 <+70>: movq %rax, %rbx 0x1001ba699 <+73>: movq 0x329ee0(%rip), %rsi ; "setEnabled:" 0x1001ba6a0 <+80>: movb -0x10(%rbp), %dl 0x1001ba6a3 <+83>: movq %rbx, %rdi 0x1001ba6a6 <+86>: callq 0x1002d23da ; symbol stub for: objc_msgSend Notice the the value of Enabled (a BOOL) is treated as 8bit (which BOOL is) and placed into the lowest 8 bits of edx with the line 'movb -0x10(%rbp), %dl'. Which means that the upper 24 bits of edx are not changed (not cleared, not signed extended, nothing, just left alone). That's because the x86-64 ABI says (https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf ): *** When a value of type _Bool is returned or passed in a register or on the stack, bit 0 contains the truth value and bits 1 to 7 shall be zero. (14) ... (14) Other bits are left unspecified, hence the consumer side of those values can rely on it being 0 or 1 when truncated to 8 bit *** However, the Objective-C BOOL type does not map to _Bool on x86-64, but to signed char. And values of that type indeed do need to (sign) extended. So this needs to be fixed in the compiler. Please file a bug report, and thanks for the analysis. Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] OSX: Setting up parameters to objc_msgSend()
This is specifically about objectivce C bridge. Hopefully this is the right forum. I am seeing a problem with how BOOL values are passed to objc_msgSend. The example is a call to NSMenuItem.setEnable(BOOL) from the lcl/interfaces/cocoa/cocoawsmenus.pas file. Here is the code: class function TCocoaWSMenuItem.SetEnable(const AMenuItem: TMenuItem; const Enabled: boolean): boolean; begin Result:=Assigned(AMenuItem) and (AMenuItem.Handle<>0); if not Result then Exit; NSMenuItem(AMenuItem.Handle).setEnabled( Enabled ); end; Here is the assembly code generated by fpc (3.1.1) for just the section where .setEnabled(Enabled) is called -> 0x1001ba68d <+61>: movq -0x8(%rbp), %rdi 0x1001ba691 <+65>: callq 0x1002016d0 ; GETHANDLE at menuitem.inc:515 0x1001ba696 <+70>: movq %rax, %rbx 0x1001ba699 <+73>: movq 0x329ee0(%rip), %rsi ; "setEnabled:" 0x1001ba6a0 <+80>: movb -0x10(%rbp), %dl 0x1001ba6a3 <+83>: movq %rbx, %rdi 0x1001ba6a6 <+86>: callq 0x1002d23da ; symbol stub for: objc_msgSend Notice the the value of Enabled (a BOOL) is treated as 8bit (which BOOL is) and placed into the lowest 8 bits of edx with the line 'movb -0x10(%rbp), %dl'. Which means that the upper 24 bits of edx are not changed (not cleared, not signed extended, nothing, just left alone). Here is the assembly code generated by XCode for a similar call to NSMenuItem.setEnable() from objective c code: 0x11258 <+440>: movq -0x40(%rbp), %rax 0x1125c <+444>: movb -0x19(%rbp), %cl 0x1125f <+447>: movq 0x185a(%rip), %rsi ; "setEnabled:" 0x11266 <+454>: movq %rax, %rdi 0x11269 <+457>: movsbl %cl, %edx 0x1126c <+460>: callq *0xd9e(%rip) ; (void *)0x7fff55e30e80: objc_msgSend Register 'edx' is the register of concern again. In this case the 8 bit BOOL value stored in %cl is placed into %edx with the line 'movsbl %cl, %edx'. In other words the 8 bit BOOL value is sign extended through all the bits of %edx. This is different than what fpc does and I think causing a problem. The top level symptom of the problem that lead me to look at this is that currently I cannot manually enable/disable NSMenuItem's because calling .setEnable doesn't work. Looking at the disassembly for .setEnable I see that the 'disable' flag for the object is stored in a 32bit record bitfield (bit 8) in NSMenuItem._miFlags; The code loads %ecx with the _miFlags, shifts left 8 to get the 'disable' bit in to 0 position, and then ands with 0x0001 to mask off all other bits. It then does a cmpl of %edx and %ecx to determine if the NSMenuITem is already in the desired state or not. If it is in the desired state then the code exists without changing the state. here is the assembly for the first part of NSMenuItem.setEnabled: AppKit`-[NSMenuItem setEnabled:]: -> 0x7fff2bff1a5f <+0>: pushq %rbp 0x7fff2bff1a60 <+1>: movq %rsp, %rbp 0x7fff2bff1a63 <+4>: pushq %r15 0x7fff2bff1a65 <+6>: pushq %r14 0x7fff2bff1a67 <+8>: pushq %rbx 0x7fff2bff1a68 <+9>: pushq %rax 0x7fff2bff1a69 <+10>: movq %rdi, %rbx 0x7fff2bff1a6c <+13>: movq 0x5c365045(%rip), %rax ; NSMenuItem._miFlags 0x7fff2bff1a73 <+20>: movl (%rbx,%rax), %esi 0x7fff2bff1a76 <+23>: movl %esi, %ecx 0x7fff2bff1a78 <+25>: shrl $0x8, %ecx 0x7fff2bff1a7b <+28>: andl $0x1, %ecx 0x7fff2bff1a7e <+31>: cmpl %edx, %ecx 0x7fff2bff1a80 <+33>: jne 0x7fff2bff1ae8 ; <+137> The FPC code works when %edx upper bits are, by luck, empty but not when they have non-zero bits. On my machine coming into the above LCL code %edx always has upper bits set and I cannot get .setEnable to work. It appears to me that objc_msgSend is expecting that parameters passed in are signed extended and that any code called by objc_msgSend will treat the registers as such. I spent some time trying to find documentation for objc runtime / objc_msgSend that shows this but didn't find anything that went into that level of detail. If objc_msgSend does expect this then I think the FPC objective c bridging is not correct. Can any of you all verify this? David Jenkins Scooter Software ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] FPC fails on overload
Done. Mantis 33875. On 6/18/18 3:01 PM, Florian Klämpfl wrote: Am 18.06.2018 um 22:00 schrieb David Jenkins: This is something that has just recently stopped working for us(with update to current trunk). We previously were using trunk rev 36812 with no problems. Please submit a bug report to mantis. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] FPC fails on overload
This is something that has just recently stopped working for us(with update to current trunk). We previously were using trunk rev 36812 with no problems. Placing a second call foo('a') calls the expected WideChar version. David On 6/18/18 1:11 PM, Marcos Douglas B. Santos wrote: On Mon, Jun 18, 2018 at 3:04 PM, David Jenkins wrote: The following code: {$MODE DELPHI} program CharOverload; uses SysUtils; procedure Foo(const aArg: UnicodeString); overload; begin WriteLn('WideString: ', aArg); end; procedure Foo(c: WideChar); overload; begin WriteLn('Char: ', c); end; begin Foo('abc'); end. Fails with current trunk fpc with the following messages [odysseus:fpc-trunk$] compiler/ppc386 ~/Desktop/test/CharOverload.pp Free Pascal Compiler version 3.1.1 [2018/06/18] for i386 Copyright (c) 1993-2018 by Florian Klaempfl and others Target OS: Darwin for i386 Compiling /Users/djenkins/Desktop/test/CharOverload.pp CharOverload.pp(19,3) Error: Can't determine which overloaded function to call CharOverload.pp(19,12) Error: Illegal type conversion: "Constant String" to "WideChar" CharOverload.pp(20,4) Fatal: There were 2 errors compiling module, stopping Fatal: Compilation aborted It fails with same messages with {$MODE OBJFPC}. Is this known. I can enter a Mantis if desired. Hey David, The compiler says "Can't determine which overloaded function to call" because both are strings. Marcos Douglas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] FPC fails on overload
The following code: {$MODE DELPHI} program CharOverload; uses SysUtils; procedure Foo(const aArg: UnicodeString); overload; begin WriteLn('WideString: ', aArg); end; procedure Foo(c: WideChar); overload; begin WriteLn('Char: ', c); end; begin Foo('abc'); end. Fails with current trunk fpc with the following messages [odysseus:fpc-trunk$] compiler/ppc386 ~/Desktop/test/CharOverload.pp Free Pascal Compiler version 3.1.1 [2018/06/18] for i386 Copyright (c) 1993-2018 by Florian Klaempfl and others Target OS: Darwin for i386 Compiling /Users/djenkins/Desktop/test/CharOverload.pp CharOverload.pp(19,3) Error: Can't determine which overloaded function to call CharOverload.pp(19,12) Error: Illegal type conversion: "Constant String" to "WideChar" CharOverload.pp(20,4) Fatal: There were 2 errors compiling module, stopping Fatal: Compilation aborted It fails with same messages with {$MODE OBJFPC}. Is this known. I can enter a Mantis if desired. Thanks David Jenkins ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] Overload failure
Sorry. Forgot to add that I tried on MacOS and Linux, 32bit & 64bit. Same message on all. David ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] mode Delphi, property overload, and svn 19564
On 4/26/16 1:02 AM, Sven Barth wrote: Overloaded properties are a more specialized variant of duplicate symbols, so of course they aren't mentioned especially in a fix. If the code you posted doesn't work in Delphi then we definitely won't add code in our Delphi mode to make it working there again, because in that case it had been a bug in FPC that had been fixed. If this code works in Delphi however then it's a bug in FPC and you should report it on Mantis. Regards, Sven I entered a Mantis (#30088) for this including example code that does compile on Delphi - as Maciej pointed out Delphi only accepts this for default properties. David Jenkins ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] mode Delphi, property overload, and svn 19564
I was trying to compile code with overloaded properties: MyClass = class function GetX(idx: integer): integer; function GetX(idxStr: string): integer; public property X[ id : integer] : integer read GetX; property X[ id : string] : integer read GetX; end; I got the 'duplicate X' error. I googled and found that previously this should compile with {$mode delphi} (a google hit from before 2011). However setting mode delphi resulted in the same error. Digging around in the compiler code and the repository I found SVN rev 19564 which was responding to Mantis 20580. I verified that the lines removed from symtable.pas:tObjectSymtable.checkduplicate lines 1298 - 1301 seem to have been the same code that allowed overloaded properties in Delphi mode (I stuck them back in and I was able to compile my overloaded properties code). So the question is: Mantis 20580 & SVN 19564 are about duplicate symbols but not overloaded properties in particular. However overloaded properties in mode Delphi appear to have gone away with that change. Was this intentional? (I tried to find discussion on this and couldn't). I guess the other question would be if I am right that overloaded properties in mode delphi don't work since that change. This is not critical to my work just something I ran across and wanted to get some clarification. I saw several discussions that indicated that overloaded properties are not available for objfpc (and not intended to be available). But I couldn't find anything recent about whether it was still intended to be available for mode delphi. Thanks David Jenkins ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)
On 3/26/16 4:19 AM, Michael Van Canneyt wrote: I have implemented a new property TStringsSortStyle = (sslNone,sslUser,sslAuto); Property SortStyle : TStringsSortStyle Read FSortStyle Write SetSortStyle; I assume the meaning is clear. - Sorted is true if SortStyle is in [sslUser,sslAuto], so it reflects actual state. - Setting sorted to True is equivalent to setting SortStyle = sslAuto - Setting sorted to false is equivalent to setting SortStyle = sslNone - Find will work on one of those values, but it will raise an exception if sortstyle = sslnone - Add will put a new string on the 'correct' place if SortStyle=sslAuto - Insert will raise an error (as it was) if SortStyle=sslAuto. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel Michael, I have checked out this code and imported it into our code base. It works great. Thank you very much. In addition the work of searching through our code and making sure we are setting SortStyle correctly has uncovered a bug in our usage. So additional thanks :D David Jenkins ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)
On 3/22/16 10:48 AM, Michael Van Canneyt wrote: On Tue, 22 Mar 2016, David Jenkins wrote: No one here holds Delphi up on a pedestal - least of all me. My viewpoint is completely practical/funcitonal - I have to make our code base work with FPC/LCL and VCL. Given the way we use find functionality (with a mixture of naturally sorted and automatically sorted lists) it has ceased to work with both (it did previously). I want to fix that as elegantly and as effectively as possible. Making suggestions for FPC improvement is a side effect - and as we both agree TStringList.Find can use some improvement. "by intention not by accident." Clearly this is not the case, given the warning in Delphi's help. I do not see it as a warning. It is a statement of requirement on the input. By passing in a naturally sorted list I am complying with that requirement (the requirement is only that it be sorted not how it is sorted). So the code works not by accident but because I have complied with the requirement and the code functions properly. Adding a check to make sure I comply with the requirement makes the code more robust and is a great thing to do. Checking for 'Sorted' actually doesn't always do this. The problem is that the Sorted flag is both a request and a loose statement of state. My list can be sorted without me requesting (through the flag) that the code sort and maintain the list. But throughout the code (Delphi and FPC) 'Sorted' is treated as an accurate mirror of list state whether the list is automatically sorted, naturally sorted, or not sorted at all (it can't tell the difference between the latter two). In the case of naturally sorted this state can be inaccurate (Sorted not set) and so some code won't run or accurate (Sorted set) but requesting unneeded actions. To me, after spending this amount of time thinking about it, this calls out for improvement as much as the concern about an accidental call to Find with an unsorted list. Though I understand that getting an erroneous result, unknowingly, is far more critical than inefficient code. However, for us we are parsing a whole lot of text strings - running through unneeded calls to sort (no matter how fast it might be on an already sorted list) adds up. And not running at all is a failure of function. In each case, there is no argument that the code can be improved. We'll sort something out in the end. Is your preference for an extra argument to Find() or an additional property ? Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel I do not have a preference. I like the auto param because 1) it is simple 2) doesn't change the interface for code that doesn't care and 3) solves the base problem. However, it doesn't decouple "Sorted" request from sorted state. An additional property could solve the base problem and clarify what the list state actually is. Though additional code would need to change to take advantage of the clarity. Maybe something (not extensibly thought on) like Sorted: boolean read GetSorted write SetSorted NaturalSorted: boolean read FNaturalSorted write FNaturalSorted SetSorted(AValue: Boolean) begin FAutoSorted := AValue; // This is the request to auto sort or not end GetSorted: Boolean begin Result := FAutoSorted or FNaturalSorted // This gets the state right for both Auto and Natural (as long is Natural truly is :D) end or have a ListType property that is ltAutoSort, ltNaturalSort, ltNone and GetSorted = ListType in [ltAutoSort, ltNaturalSort] The additional properties (not necessarily implemented as above) is attractive as it seems like a more complete solution. There is still the chance of an unsorted list getting by. Adding Denis' solution in .Find along with the new properties would narrow the window of unsorted lists coming through while still allowing bypass of sorting code for explicitly set Naturally sorted lists (lists with NaturallySorted=True but not actually sorted could still sneak through). All the above are fine with me. David ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)
On 3/22/16 9:53 AM, Denis Kozlov wrote: Please consider the following implementation logic, I think it covers all angles: procedure Find(const S: string; out Index: Integer):Boolean; begin if Sorted then Result := FindSorted(S, Index); else begin Index := IndexOf(S); Result := (Index >= 0); end; end; procedure FindSorted(const S: string; out Index: Integer; CheckSorted: Boolean = True):Boolean; begin if CheckSorted and not Sorted then raise Exception.Create('List must be sorted'); // search logic here... end; Denis ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel Denis, I like how this solves the issue of calling find on truly unsorted lists. My only quibble with this is that 'Sorted' still does not reflect the actual state of the list. For a naturally sorted list there is still unnecessary calls to sort both in your suggested code above and in the existing code (if sorted is set). Can that be handled as well? 'Sorted' right now is a request and an expression of state. As an expression of state it is only valid if the request has been first made. David ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)
On 3/22/16 9:43 AM, Michael Van Canneyt wrote: Here we disagree. It IS buggy behavior. Delphi is not sacrosanct, it does contain bugs like any software. This is one of them. No one here holds Delphi up on a pedestal - least of all me. My viewpoint is completely practical/funcitonal - I have to make our code base work with FPC/LCL and VCL. Given the way we use find functionality (with a mixture of naturally sorted and automatically sorted lists) it has ceased to work with both (it did previously). I want to fix that as elegantly and as effectively as possible. Making suggestions for FPC improvement is a side effect - and as we both agree TStringList.Find can use some improvement. And I am fine disagreeing. My definition of 'bug' is again completely functional. If I knowingly stick in a naturally sorted list into Find(), the code operates as expected without error, and I get the desired result. Both user and producer operated as expected - by intention not by accident. I do not see a bug there. If I stick in a non-sorted list (knowingly or unknowingly) then results are undefined. Is that user error or buggy code? It certainly isn't robust code and can be improved. Label it as you like I am only interested it seeing it improved. As we have all pointed out there is some inherent issues with a function traditionally named 'find' that essentially hides input requirements (again label that as you like). Michalis has pointed out that TFSMap.Find has a similar issue. The other weakness I see in the current traditional implementation (Delphi and FPC) is that the 'Sorted' flag is somewhat loosely coupled to the actual state of the list i.e. it can be in a sorted state and the flag does not reflect that at all. To me it seems that the flag really means 'auto sort this please'. Once it is enabled the code will sort and maintain sort. But the code is also intended to support naturally sorted lists and not induce the overhead of auto sort. In that situation the sorted property has nothing to do with the actual state of the list. IMO better designed code would account for this. Perhaps it should have been called TStringSortedList and enforced auto sort all the way through instead of purposely handling both sorted and unsorted lists. As to our decision to use TStringList directly. Whether we use it directly or create our own doesn't fix the code that we all agree is insufficiently robust, 'buggy', 'prone to allow bad use', or whatever label you want to use. So I find your concern touching but not applicable to the point at hand. Furthermore TStringList has provided exactly what we needed (and we have been careful to only pass sorted - natural or automatic - to it). Why would we purposely rebuild the wheel. Libraries exist for just this. And that's all I have to say about that (as Forrest Gump said). Thanks for the discussion. David ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)
On 3/22/16 4:15 AM, Michalis Kamburelis wrote: 2016-03-22 8:18 GMT+01:00 Ondrej Pokorny: This would be my preference too --- just raise the exception. Or just fallback on linear search using IndexOf, if the list is not known to be sorted. In my experience, it's a common bug right now to call Find on an unsorted list. I stumbled on this bug, and I saw other people stumbling on it too. Even though it's clearly documented that "Find only works on sorted lists", it's still a problem --- you just don't check documentation for something as obvious as "Find". Just like you don't check documentation of "IndexOf", "Add" and other seemingly-obvious methods. A nice API would call the method "FindInSorted" if the method was assuming the list to be sorted, right? The case when the list is already known to be naturally sorted should be marked by the caller, e.g. by an optional parameter to Find (like AssumeAlwaysSorted=true), or by using special method to assume a sorted list. Also, setting "Sorted := true" on an already-sorted list should be rather fast (quicksort on an already-sorted list should go fast, in linear time; sure, it's not zero time, but still it's often fast enough). But the default should really be safer (IMHO), which is either 1. "raise exception" (predictable, and easy to catch the bug --- developer will either make it sorted, or use IndexOf instead), or 2. fallback to linear search (so it always works correctly, but with a speed penalty if you forgot to sort). Delphi behavior in this case (blindly trust the list is already sorted) is just a bug IMHO, and this case warrants breaking Delphi compatibility. Also: for consistency, it would be great to apply any fixes developed here also to FGL unit containers, as the TFPSMap.Find shares the same problem: it's name is simply "Find", and it assumes the contents to be Sorted. Regards, Michalis ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel I'd also be fine with this suggestion of the optional AssumeAlwaysSorted=true parameter as a way of maintaining the particular functionality we are interested in (instead of the ManualSorted property). David ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)
On 3/22/16 2:01 AM, Michael Van Canneyt wrote: But you agree that if Find is called on an unsorted list, bogus data will be returned ? Or, worse, an never-ending loop may occur ? In short, as you say, an "error condition" can ensue without you knowing it. That is a bug. So, in my opinion (and of some others), Find is implemented buggy in Delphi. Consider the buggyness a given in what follows. If we consider something a bug in Delphi, we do not copy the bug. You happen to rely on this buggy behaviour. This is of course unfortunate. I attempted to fix this bug using a not too invasive method. Originally I simply wanted to raise an exception, but that was deemed too invasive. There are now several options: 1. I change the code to raise an exception instead (as was my original plan) 2. I change the code to resort to a linear search if sorted is false. 3. I introduce a boolean property that determines whether Find does any check. By default the check will be done, to warn people they're doing something stupid. If they override the check, we can assume they know what they are doing. 4. Combine 1 and 3. Or, 5. You override sort so it does nothing. It is virtual. You can then set sorted to True, no sort will occur, and find will do it's job. 6. You use another TStringList where you change find to suit your needs. All it takes for you is to copy the implementation, you can keep the same name, and insert the unit after the classes unit in places where you need it. It's your call which of the 5 methods is used. But one thing is sure: we're not reverting the behaviour back to the buggy behaviour. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel #1 is what Zoe Peterson (my coworker) has suggested as well. Without that exception (as the code now is) there is no warning issued just an ambiguous return of False. Which means that the code is still buggy as the user could assume that the Index value points to next insert spot and instead it is out of range and causes a crash. Setting Index value to -1 would be a better indicator of bad usage than just returning False (with raising an exception still being the best warning). Keep in mind though that being able to call find on a manually sorted list (Sorted <> true) is not buggy behavior (this is the Delphi compatibility that we are interested in maintaining). In which case adding in #3 would be necessary. So I guess I am for #4. I would suggest that the added boolean flag be named to indicate that the list is manually sorted (ManualSorted ?) rather than the flag being just a 'bypass check' indicator. The check in Find would be "if not Sorted or not ManualSorted then raise exception'. But that's just a personal preference and not something that I feel extra committed to. My second choice would be #1 by itself. David ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)
On 3/21/16 3:44 PM, Michael Van Canneyt wrote: The reason for this behaviour is that find needs to be sure that the list is sorted. If it thinks the list is not sorted, the result cannot be guaranteed to be correct, and this is an error condition. What I don't understand about these discussions is: TStringList is just one possible implementation of TStrings. It is only there for your ease of use. If you don't like it, you can use another one. You can find several. There is one in inifiles, the LCL probably also contains a couple. If all APIs work with TStrings, then they don't care what TStrings descendent you use. So you are free to use one that does whatever you want. Anyone declaring an API that explicitly expects TStringList, is simply doing something wrong, in my view. This is Object Pascal for a reason, after all. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel I understand the need for the list to be sorted and agree that calling find on an unsorted list is an error condition. I am not convinced that current change deals with that well. For one, the Sorted flag and actual state of the list are not directly linked. I can manually sort the list so that Find binary search will work just fine. But Find will exit before the binary search can occur - without any indication why. Ff the list is not sorted, I don't think the current change creates a true error response to the error condition. Returning False indicates string not found - not an error. Furthermore I think the change makes the error condition worse by leaving values in Index that can cause crashes beyond just the error condition of not finding the right string. Raising an exception if not Sorted would be an error response. Or providing some feedback to the user to indicate the difference between not found and error condition. We can use our own descendant of TStrings or we could apply a local patch to TStringList as already mentioned. So we can actually create a work around. Our interest was in pointing out a change in fpc code that we thought was a regression rather than an improvement. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)
On 3/21/16 2:55 PM, Michael Van Canneyt wrote: We can introduce a property which disables the check, if you want. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel However.. now that I've thought about it some more. That change would be nice and all for us but doesn't it just muddle the picture even more for anyone else using the code? I'm feeling tempted to argue against my side a little. If the change is correct i.e. makes for better code or behavior then it should stay and we'll go ahead and take it out in our local files if we don't like it (we'll grumble at having to maintain a local patch be we already have a few of those). My thought is that it doesn't make for better code or behavior while at the same time breaking Delphi compatibility. Delphi compatibility isn't the golden standard but it seems any breakage should be for a good reason. David ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)
On 3/21/16 2:55 PM, Michael Van Canneyt wrote: We can introduce a property which disables the check, if you want. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel That would work for us. Our other option is to pull the check out in our local version of stringl.inc. But we prefer to maintain as few local patches as possible. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] Questions on TStringList.Find change (Mantis 28744)
I just ran across the change that checks Sorted at beginning of find and exits if Sorted = False. This has caused some problems for us a) We have lists that are sorted manually and we'd like to continue keeping them sorted manually (and be able to call .insert()). This means not setting the sorted flag. But without setting 'sorted' we can no longer use find. We are sharing code between VCL and FPC - delphi compatibility has been broken. b) The change, in my opinion, hasn't solved the unpredictable response problem. There is still nothing to indicate to a caller that they have called the function inappropriately i.e. they do not know why find has returned false. Furthermore the documentation also indicates that if false is returned then 'Index' will contain the position where the string should be inserted. Index used to at least be within the range of FCount or 0. Now the value 'Index' is even more indeterminte as the code exits before Index has been set to anything. It has gone from possibly placing a string at a wrong location to possibly causing a crash with index out of range. It could be argued whether this is worse but it certainly doesn't seem to have made the situation any better for people blindly misusing Find an unsorted list - while at the same time breaking Delphi compatibility and the option to manually keep lists sorted. Thoughts? David Jenkins da...@scootersoftware.com ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] safecall_exceptions in OSX
Thanks Jonas, I enabled tf_safecall_exceptions for system_i386_darwin_info and it is working for my particular need. I am using jcl (JclCompression) and the unix port of 7zip (p7zip) to provide 7z support for our app. Official current JclCompression is MSWINDOWS only and uses safecall for the interface connections to the 7z.dll. By enabling the safecall result passing for darwin I am able to use JclCompression with 7z.so with only slight modifications. So far I have seen no issues. I would not claim that this is a full test of XPCOM/safecall_exceptions on OSX. Regards David Jenkins ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] safecall_exceptions in OSX
I have been using the safecall functionality in linux and it has been working. I now am porting the same code to OSX and find that safecall_exceptions is not turned on. In particular I need the functionality that catches the HRESULT and passes it back to the calling function. I see that tf_safecall_exceptions is only enabled in tsysteminfo for i_linux and i_win. Is it possible to enable tf_safecall_exceptions for i_macos. Thanks David Jenkins da...@scootersoftware.com ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] nestedprocvar questions
Some questions about 'nestedprocvars' mode switch We have a simplified version of the nested procedure calling demonstrated in tests/test/tmaclocalprocparam3d.pp. It looks more or less like: {$mode DELPHI} {$modeswitch nestedprocvars} type tnestedprocvar = function(AArg: string): boolean; procedure p1(AArg: string; pp: tnestedprocvar); begin if pp(AArg) then writeln('true'); end; procedure q; function r(AArg: string): boolean; begin writeln(AArg) Result := true; end; begin p1('test string', @r); end; Notice that it is $MODE DELPHI, that the proc var is a function, and that we do not access any external variables in the nested function. Question #1: There seems to be an interaction between $MODE DELPHI and the 'is nested' construct. I.e. I cannot put the 'is nested' after the tnestedprocvar type and do the function passing with '@r'. If I do the compiler complains about getting a pointer (@r) when it was expecting a function (..): boolean is nested. So either I remove the'@' and just pass 'r' or I do not include the 'is nested'. Is this correct? Question #2: This code is being compiled both with Delphi compiler and with FPC. Delphi handles the nesting with no problem and with no 'is nested' directive. Should nestedprocvar be included automatically with $MODE DELPHI for compatibility? Question #3: If we set up our code as above can we expect the compiler to be consistent in parameter set up for the next while? Question #4: If we set up our code as above (with no 'is nested') would it be safe to include access of an external variable (internal to procedure q) to the nested function? ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] FreePascal Git Repo and 2_6 branch
On 4/28/2012 12:23 PM, Graeme Geldenhuys wrote: What I can do in an automated fashion, is to simply mirror the 2.6 fixes branch as a separate git repository (with limited history - going back to when 2.6 fixes branch was started). If this would be sufficient, I can set it up on Wednesday when I am back in the office. That's no trouble. For my situation this would be sufficient. I have some local patches that git-rebase does a nice job of plopping on the head of the branch whenever there are changes. Right now those patches are sitting on trunk but I would like to move them to fixes-2_6 and maintain them there. I had started to do a 'git svn clone' of the fpc repository myself and after it ran for 16 hours wondered if there were a better way. Creating the limited history 2.6 fixes branch repository myself is probably also an option if you have better things to do. Thanks David ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
[fpc-devel] FreePascal Git Repo and 2_6 branch
I am wondering if Graeme can update his FreePascal git mirror to include the 2_6 branches. Thanks David Jenkins ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
[fpc-devel] TMultiReadExclusiveWriteSynchronizer
Under Delphi if the TMultiReadExclusiveWriteSynchronizer writelock is held a read is not blocked if the ThreadID for the read is the same as the ThreadID for the write. Under FreePascal if writelock is held the read is always blocked regardless of ThreadID or anything else (implemented in the BeginRead method). I have some third party code that assumes that TMultiReadExclusiveWriteSynchronizer will work as it does in Delphi. I am wondering if the freepascal implementation is purposeful (read block even when in same thread is intentional) and I should talk to my third party vendor. Or if this is something that could/should be addressed in FreePascal. Thanks David Jenkins Scooter Software ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel