-
Content Count
16 -
Joined
-
Last visited
Community Reputation
11 GoodRecent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
-
Let me try and see if I can reproduce this error with a simple sample project. and post that here later.
-
As has been clarified by Hick Hodges a few times before (when he was working for Emba), all is exactly as Andy wants it. And he does have access to the source as per agreement. And no he does not get paid (as far as we know) and (as far as we know) that's how he wants it. This point keep coming up again and again and it's getting rather old, just be happy with the work Andy is doing and take your blessings where you can get them. Yes Emba should do more, better, faster etc but it is as it is.
-
@jbg Hi Andy, I'm getting an error when compiling my project after installing the Delphi fix pack in Rio Community edition version: Embarcadero® Delphi 10.3 Version 26.0.32429.4364 Compiler Speed Pack x86 6.4 for Delphi 10.3 Windows 10 version 10.0 Build 17134 64-Bit edition When I run a 64-bit application under the debugger (F9) the following error pops up: Debugger Assertion Failure "apiOK" in ..\win32src\w64mgr.cpp at Line 79 [203B7664]{dbkdebugide260.bpl} Debug.TDebugKernel.msgBox (Line 5945, "Debug.pas" + 30) + $0 [2DFB6EB3]{bordbk260.dll} Unknown function at DllUnregisterServer + $5037 [2DFD37D6]{bordbk260.dll} Unknown function at @isDbkLoggingOn$qv + $98FE [2E067FC9]{bordbk260.dll} Unknown function at @isDbkLoggingOn$qv + $9E0F1 [2DFCA660]{bordbk260.dll} Unknown function at @isDbkLoggingOn$qv + $788 [2DFCA6DB]{bordbk260.dll} Unknown function at @isDbkLoggingOn$qv + $803 [2E0617AD]{bordbk260.dll} Unknown function at @isDbkLoggingOn$qv + $978D5 [189FB134]{bordbk260N.dll} Unknown function at @isDbkLoggingOn$qv + $302BC [189CDBB5]{bordbk260N.dll} Unknown function at @isDbkLoggingOn$qv + $2D3D [18A01FB3]{bordbk260N.dll} Unknown function at POSTEDHOOKPROC + $113F [18A0176F]{bordbk260N.dll} Unknown function at POSTEDHOOKPROC + $8FB [50067E99]{rtl260.bpl } System.@IntfCopy (Line 38197, "System.pas" + 6) + $0 [2E070CC5]{bordbk260.dll} Unknown function at @isDbkLoggingOn$qv + $A6DED [2DFB908C]{bordbk260.dll} Unknown function at DllUnregisterServer + $7210 [2E06F91B]{bordbk260.dll} Unknown function at @isDbkLoggingOn$qv + $A5A43 [2E06214A]{bordbk260.dll} Unknown function at @isDbkLoggingOn$qv + $98272 [2E062AA4]{bordbk260.dll} Unknown function at @isDbkLoggingOn$qv + $98BCC [2E0628D3]{bordbk260.dll} Unknown function at @isDbkLoggingOn$qv + $989FB [2E062033]{bordbk260.dll} Unknown function at @isDbkLoggingOn$qv + $9815B [2E061999]{bordbk260.dll} Unknown function at @isDbkLoggingOn$qv + $97AC1 [2E061521]{bordbk260.dll} Unknown function at @isDbkLoggingOn$qv + $97649 [2DFB7AEC]{bordbk260.dll} Unknown function at DllUnregisterServer + $5C70 [203B6357]{dbkdebugide260.bpl} Debug.TDebugKernel.CreateProcess (Line 5464, "Debug.pas" + 17) + $63 [0B6AE315]{IDEFixPack.dll} DbkCreateProcessWithRelHostApp.TDebugKernel_CreateProcessHook (Line 46, "DbkCreateProcessWithRelHostApp.pas" + 4) + $23 [203BDD5C]{dbkdebugide260.bpl} Debug.TProcess.CreateProcess (Line 9037, "Debug.pas" + 1) + $2D [203C4D51]{dbkdebugide260.bpl} Debug.TDebugger.DoCreateProcess (Line 11959, "Debug.pas" + 74) + $24 [203C4EF8]{dbkdebugide260.bpl} Debug.TDebugger.CreateProcess (Line 11986, "Debug.pas" + 7) + $2F [203C5A27]{dbkdebugide260.bpl} Debug.TDebugger.Run (Line 12395, "Debug.pas" + 23) + $33 [203C675C]{dbkdebugide260.bpl} Debug.TDebugger.Run (Line 12759, "Debug.pas" + 164) + $4D [203C062E]{dbkdebugide260.bpl} Debug.TDebugger.Run (Line 10370, "Debug.pas" + 0) + $2 [20866811]{coreide260.bpl} DebuggerMgr.TDebuggerMgr.Run (Line 2067, "DebuggerMgr.pas" + 21) + $5 [004AE277]{bds.exe } AppMain.TAppBuilder.RunRun (Line 3386, "AppMain.pas" + 1) + $3 [5017361B]{rtl260.bpl } System.Classes.TBasicAction.Execute (Line 17028, "System.Classes.pas" + 7) + $3 [50CCDE62]{vcl260.bpl } Vcl.ActnList.TCustomAction.Execute (Line 261, "Vcl.ActnList.pas" + 19) + $35 [0B6A880E]{IDEFixPack.dll} RefactoringActionUpdateFix.CustomActionExecute (Line 87, "RefactoringActionUpdateFix.pas" + 4) + $0 [50173483]{rtl260.bpl } System.Classes.TBasicActionLink.SetAction (Line 16939, "System.Classes.pas" + 0) + $3 [50CE54EC]{vcl260.bpl } Vcl.Controls.TControl.Click (Line 7501, "Vcl.Controls.pas" + 7) + $7 [50D644BC]{vcl260.bpl } Vcl.ComCtrls.TToolButton.Click (Line 21635, "Vcl.ComCtrls.pas" + 0) + $0 [50CE59B7]{vcl260.bpl } Vcl.Controls.TControl.WMLButtonUp (Line 7642, "Vcl.Controls.pas" + 7) + $6 [50CE4FAA]{vcl260.bpl } Vcl.Controls.TControl.WndProc (Line 7387, "Vcl.Controls.pas" + 91) + $6 [5005FE07]{rtl260.bpl } System.TObject.Dispatch (Line 18332, "System.pas" + 11) + $0 [09918E3E]{themeloader260.bpl} Idetheme.Vclstylehooks.TIDEStyleHook.WndProc + $7A [50067E88]{rtl260.bpl } System.@IntfClear (Line 38150, "System.pas" + 10) + $0 [099188F7]{themeloader260.bpl} Idetheme.Vclstylehooks.TIDEStyleHook.HandleMessage + $B7 [50067E88]{rtl260.bpl } System.@IntfClear (Line 38150, "System.pas" + 10) + $0 [500640D8]{rtl260.bpl } System.@FinalizeArray (Line 32811, "System.pas" + 144) + $0 [50CE4BE4]{vcl260.bpl } Vcl.Controls.TControl.Perform (Line 7165, "Vcl.Controls.pas" + 10) + $8 [50CE926E]{vcl260.bpl } Vcl.Controls.GetControlAtPos (Line 9967, "Vcl.Controls.pas" + 4) + $75 [50CE9336]{vcl260.bpl } Vcl.Controls.TWinControl.ControlAtPos (Line 9990, "Vcl.Controls.pas" + 13) + $E [50CE4BE4]{vcl260.bpl } Vcl.Controls.TControl.Perform (Line 7165, "Vcl.Controls.pas" + 10) + $8 [50CE9404]{vcl260.bpl } Vcl.Controls.TWinControl.IsControlMouseMsg (Line 10014, "Vcl.Controls.pas" + 15) + $29 [50CE9A0C]{vcl260.bpl } Vcl.Controls.TWinControl.WndProc (Line 10191, "Vcl.Controls.pas" + 112) + $6 [50D665E9]{vcl260.bpl } Vcl.ComCtrls.TToolBar.UpdateButtonState (Line 22913, "Vcl.ComCtrls.pas" + 11) + $27 [50D6662A]{vcl260.bpl } Vcl.ComCtrls.TToolBar.UpdateButtonStates (Line 22924, "Vcl.ComCtrls.pas" + 3) + $4 [50D69060]{vcl260.bpl } Vcl.ComCtrls.TToolBar.WndProc (Line 24514, "Vcl.ComCtrls.pas" + 104) + $6 [50CE9178]{vcl260.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 9944, "Vcl.Controls.pas" + 3) + $6 [50174370]{rtl260.bpl } System.Classes.CalcJmpOffset (Line 17554, "System.Classes.pas" + 0) + $0 [50E3E7A7]{vcl260.bpl } Vcl.Forms.TApplication.ProcessMessage (Line 10724, "Vcl.Forms.pas" + 23) + $1 [50E3E7EA]{vcl260.bpl } Vcl.Forms.TApplication.HandleMessage (Line 10754, "Vcl.Forms.pas" + 1) + $4 [50E3EB1D]{vcl260.bpl } Vcl.Forms.TApplication.Run (Line 10892, "Vcl.Forms.pas" + 26) + $3 [00517FFA]{bds.exe } bds.bds (Line 214, "" + 7) + $7 Uninstalling the IDE-fix pack (ouch, that hurts) resolves the issue.
-
JMP to expernal methods <> inlined call to external method, bug or correct design?
Johan Bontes posted a topic in RTL and Delphi Object Pascal
I have the following code (Delphi Berlin): interface type TSliver = record public private case integer of 8: (Data8: int64); end; TSlice = record private FData: array [0..63] of byte; end; TSliverHelper = record helper for TSliver class function NS(const North, South: TSlice; out Changed: TSliverChanges): TSliver; static; inline; end; {$L 'C:\mydir\AVXGenerate.o'} //imported assembly generated by lazarus. procedure AVXGENERATE_TSLIVERHELPER_NS; external name 'AVXGENERATE_$$_TSLIVERHELPER_NS'; //no parameters for simplicity. implementation class function TSliverHelper.NS(const North, South: TSlice; out Changed: TSliverChanges): TSliver; {inline;} //RCX =North: PSlice //RDX =South: PSlice //R8 = Changed: PSliverChanges ((scUnchanged=0, scChanged=1, scInvalid=3)); //RAX = Result: TSliver (as Int64) begin AVXGENERATE_TSLIVERHELPER_NS; end; //asm // jmp AVXGENERATE_TSLIVERHELPER_NS; //end; The asm method works correctly, the inlined method does not. If we look at the generated code it's easy to see why this happens. a:= TSliver.NSTest(N,S,statusA); //a = -1 UnitTests.pas.877: b:= TSliver.NS(N,S, statusB); 00000000009A77CE 488D8C2480000000 lea rcx,[rsp+$0080] 00000000009A77D6 488D542440 lea rdx,[rsp+$40] 00000000009A77DB 4C8D44242E lea r8,[rsp+$2e] 00000000009A77E0 E82B5E0100 call TSliverHelper.NS 00000000009A77E5 4889442430 mov [rsp+$30],rax //b = 7 why? //Let's see what's happening in the inlined method. class function TSliverHelper.NS(const [ref] N,S: TBigRec; out status: TEnumRec): UInt64_Rec; Unit2.pas.4360: begin 00000000009BD610 55 push rbp 00000000009BD611 4883EC30 sub rsp,$30 00000000009BD615 488BEC mov rbp,rsp Unit2.pas.4361: AVXGENERATE_TSLIVERHELPER_NS; 00000000009BD618 E833350000 call AVXGENERATE_TSLIVERHELPER_NS //external asm procedure with no declared params. Unit2.pas.4362: end; //At this point RAX = result = -1, all OK 00000000009BD61D 488B4528 mov rax,[rbp+$28] //Oops, RAX gets overwritten, why? <<<<??????????????????????? 00000000009BD621 488D6530 lea rsp,[rbp+$30] 00000000009BD625 5D pop rbp 00000000009BD626 C3 ret Why does the compiler insert an assignment to RAX? I have not instructed it to do anything of the sort. Compiling this code also does not issue a warning that Result might be unassigned. Why does the compiler do this? (I know I can fix this by declaring the external proc as a function, but that's beside the point). EDIT When we redefine the external proc as a function and change the inline method as shown below, correct code gets generated. It also gives some insight what is going on: Unit2.pas.4360: begin 00000000009BD610 55 push rbp 00000000009BD611 4883EC30 sub rsp,$30 00000000009BD615 488BEC mov rbp,rsp Unit2.pas.4361: Result:= AVXGENERATE_TSLIVERHELPER_NS; 00000000009BD618 E833350000 call AVXGENERATE_TSLIVERHELPER_NS 00000000009BD61D 48894528 mov [rbp+$28],rax //pointless stack trashing Unit2.pas.4362: end; 00000000009BD621 488B4528 mov rax,[rbp+$28] //the exit code expects Result to be in the stackframe. 00000000009BD625 488D6530 lea rsp,[rbp+$30] 00000000009BD629 5D pop rbp 00000000009BD62A C3 ret The compiler is just copy pasting its exit code, regardless of the actual code in the body. Note that I've compiled the code with no stackframes -
Creating Component Templates in Delphi
Johan Bontes replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
Nice, when was this feature added? I'd not noticed it. -
Does anyone have some library/unit to make coding of tokeniser/parser/somekind of tree easier?
Johan Bontes replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
What does that mean? Do you want a Pascal parser, or an any/all language parser? The former exists, the latter does not. Obviously there are parsers for other languages, just not one parser for every language. There is however Langserver you might want to have a look at that. -
Does anyone have some library/unit to make coding of tokeniser/parser/somekind of tree easier?
Johan Bontes replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
@Stefan Glienke I'm happy to put the commits into any format that will help get them merged. If you want them in another format, I'll do that. I'll have a look at what steps to follow. -
Does anyone have some library/unit to make coding of tokeniser/parser/somekind of tree easier?
Johan Bontes replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
@Tommi Prami That's easy: https://github.com/RomanYankovsky/DelphiAST You might want to try the version with all my patches in it: https://github.com/JBontes/DelphiAST It seems Roman Yankovsky has not had time to integrate all my issues yet. It **is** a very mature library and using it will serve you well. If you want to change the code, grokking the calls between the different parser levels does take some getting used to. I suggest first reading up on the difference between a parser and a lexer if you want to do that. PS don't be put off by the XML output, that's just a cheap trick to display the contents of the tree. You don't need it to work with DelphiAST. -
Welcome to the English speaking Delphi-PRAXiS
Johan Bontes replied to Daniel's topic in Community Management
I'm not sure this is the right place for feature requests, but here goes: A: hide signature lines Would it be possible to have the option to hide signature lines? I find them to be such a distraction. Of course it would be even better IMO if signature lines were not allowed at all, but at least the option to hide them would help a lot. Just found the "hide all signatures" option at https://en.delphipraxis.net/settings/signature/ B: inline code I would really like to be able to have inline code in a line. A `monospace` button (in addition to bold, italic, etc would do the trick nicely. C: Disable animating emoji Animation of any kind just sucks, enough said. D: position replies indented relative to the original post If I reply to a post, then that post just goes to the bottom. I can quote part or all of it, but that's a bit of a waste as it just repeats the content, which is often (not always) just noise. It would be great to have a threaded view where replies are underneigh the original post and indented (with a stop if the nesting gets too deep). Overall the forum works kind of nice, it does take up a **lot** of space relative to G+, but it works smooth enough. Thanks for making this available on such sort notice. type TX = record private class var x: integer; private Fdata: integer; public class operator Add(a,b: TX): TX; end; I love how the code formatter knows about post-1980 language features, unlike the one stackoverflow uses. -
Time bomb
Johan Bontes replied to Attila Kovacs's topic in Algorithms, Data Structures and Class Design
In that case can you please explain what the nature of your (time)bomb is? I thought it was the issue that the const input got changed by the proc, but that does not seem to be your problem. -
New in 10.3: IDE UI Improvements in the Main Window
Johan Bontes replied to Mohammed Nasman's topic in Delphi IDE and APIs
I'm strangely excited about this release, in a way that I have not been for a while. The language improvements mostly, but a cleaner IDE is just very nice icing on the cake. -
Time bomb
Johan Bontes replied to Attila Kovacs's topic in Algorithms, Data Structures and Class Design
The way to deal with this is to have a function return a string whenever possible, that way it is clear in the calling code that `S` is being overwritten. Never output the same managed type of data that you allow as input in a var or out parameter. function y(const input: string; out Success: boolean): string; begin Result:= input + '1'; // end; status:= x(S,S); //Looks harmless S:= y(S, status); //The danger is clearly visible in the calling code Alternatively he compiler could issue a warning when a const parameter is also passed as a var/out parameter. also this code does not make a whole lot of sense: if x(S,S) then .... ////^^^^^ ////hiding dangerous -work- stuff with side-effects in an if statement. You should never do unconditional work inside an if statement. That's too unexpected. -
Inline Variables Coming in 10.3
Johan Bontes replied to Marco Cantu's topic in RTL and Delphi Object Pascal
Ah, yes obviously! -
Inline Variables Coming in 10.3
Johan Bontes replied to Marco Cantu's topic in RTL and Delphi Object Pascal
No the type does not have to be guessed, it is a `TInterfacedObject`. As is stated in the create statement. What would be great though is to have static methods for interfaces: class function IMyInterface.Create: IMyInterface; static; //or even better constructor IMyInterface.Create; Obviously internally the constructor would translate to a static class function returning the interface. We can already do this by wrapping interfaces inside records and using implicit operator overloads, but that's a lot of typing. There is nothing stopping the compiler from helping us here, it's just a bit of syntactic sugar. Then we can just write var IMyInf:= IMyInterface.Create; Just like we can do in Java 8. (Yes, I dislike java just as much as everyone else, but static interface methods are a pretty cool feature.) -
Inline Variables Coming in 10.3
Johan Bontes replied to Marco Cantu's topic in RTL and Delphi Object Pascal
This was already the case with normal var declarations. Obviously if you want the var to be a different type than the R-value then you'll have to declare that type. In your own code you can fix this by declaring class functions like so: type TMyClass = class(TInterfacedObject, IMyIntf) public class function CreateIntf: IMyInf; end; ... class function TMyClass.CreateIntf: IMyInf; begin Result:= TMyClass.Create; end; //Now type inference works just fine. //Alternatively perhaps typecasting works? var IMyVar := IMyInf(TMyClass.Create);