Question on Calling Conventions (for: PascalScript on Win x64)

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Question on Calling Conventions (for: PascalScript on Win x64)

Alexander Hofmann
Hi there.

This is a cross-post (cross-mail ?) to http://www.lazarus.freepascal.org/index.php/topic,17978.0.html as I got the hint there that it might be better to ask on the list instead of in the forum, at least concerning the calling conventions - but I'll ask the whole lot, anyway; I hope that's ok (and, yes, I made the mistake to ask on the Lazarus list before, so I sincerely hope I won't bother the wrong people again, sorry)

Question:
Is there any difference in the calling convention on x64-Systems between Delphi and Lazarus? I could only find the "standard" information on Windows x64 calling conventions, without special care of constructors, if there is any.

The reason why I'm asking is the following:
I'm trying to get PascalScript running (completely, it does up to some extend) on Win x64. I had to do some changes in x64.inc, see below - but as far as I know, that should work - and it does, for all kinds of calls, except calling constructors on Components.
Scripts like the following will crash the Program with a SIGSEGV.

program Script;
var
  f:TForm;
  b:TButton;
begin
  f:=TForm.CreateNew(nil); //<- Works
  b:=TButton.Create(f); //<- crash
  b.Parent:=f;
  f.Show;
end.

Crash in the Program is here:

CLASSES_TCOMPONENT_$__INSERTCOMPONENT$TCOMPONENT 
000000000044F900 4883ec38                 sub    $0x38,%rsp
000000000044F904 48895c2420               mov    %rbx,0x20(%rsp)
000000000044F909 4889742428               mov    %rsi,0x28(%rsp)
000000000044F90E 4889cb                   mov    %rcx,%rbx
000000000044F911 4889d6                   mov    %rdx,%rsi
000000000044F914 4889da                   mov    %rbx,%rdx
000000000044F917 4889f1                   mov    %rsi,%rcx
000000000044F91A 4889f0                   mov    %rsi,%rax
000000000044F91D 488b00                   mov    (%rax),%rax
000000000044F920 ff9068010000             callq  *0x168(%rax)  <-- crash 

The same Script runs fine when the Application was compiled with x86 Lazarus 1.0. By the way: creating a TObject with e.g. o:=TObject.Create doesn't break at al.

Interestingly (and that is how I came to ask about the calling conventions), when I start debugging <SomeClass>.Create(aOwner:TComponent)-Type of Constructors, there is some difference in the Register values, depending on whether the Constructor was called from "pure" FPC-Code or the Script (at least so it seems):

o Called from FPC: rcx: 0 (nil), rdx: Class Reference, r8: Value of aOwner
o Called from Script: rcx: Class Reference, rdx: 1 (!?), r8: Value of aOwner (at least so it seems)

Did anybody else stumble about that problem before?

Thanks for your help!


I can compile the downloadable latest stable version from RemObject's website (the one with the EXE-Installer) as well as the latest development version from https://github.com/remobjects/pascalscript OR (that's not in the Forum) the PascalScript-version included in Lazarus' SVN, no Problem there, after two small changes in x64.inc (see below). My knowledge of Assembler is limited at best, but It works for calling other types of methods...

Index: x64.inc
===================================================================
--- x64.inc    (revision 38441)
+++ x64.inc    (working copy)
@@ -14,7 +14,7 @@
   _RCX, _RDX, _R8, _R9: IPointer;
   var _XMM0: Double;
   _XMM1, _XMM2, _XMM3: Double;
-  aStack: Pointer; aItems: IntPtr); assembler; {$IFDEF FPC}nostackframe;{$ENDIF}
+  aStack: Pointer; aItems: PtrUInt); assembler; {$IFDEF FPC}nostackframe;{$ENDIF}
 asm
 (* Registers:
     RCX: Address
@@ -37,7 +37,7 @@
   mov rdx, aStack
   jmp @compareitems
 @work:
-  push [rdx]
+  push qword ptr [rdx]
   dec rcx
   sub rdx,8
 @compareitems:


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

signature.asc (265 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Question on Calling Conventions (for: PascalScript on Win x64)

Florian Klämpfl
Am 05.09.2012 18:27, schrieb Alexander Hofmann:

> Hi there.
>
> This is a cross-post (cross-mail ?) to
> http://www.lazarus.freepascal.org/index.php/topic,17978.0.html as I got
> the hint there that it might be better to ask on the list instead of in
> the forum, at least concerning the calling conventions - but I'll ask
> the whole lot, anyway; I hope that's ok (and, yes, I made the mistake to
> ask on the Lazarus list before, so I sincerely hope I won't bother the
> wrong people again, sorry)
>
> Question:
> Is there any difference in the calling convention on x64-Systems between
> Delphi and Lazarus? I could only find the "standard" information on
> Windows x64 calling conventions, without special care of constructors,
> if there is any.

Constructors are not part of the Win x64 ABI so any compiler is free to
pass the hidden parameters needed by a constructor.

>
> The reason why I'm asking is the following:
> I'm trying to get PascalScript running (completely, it does up to some
> extend) on Win x64. I had to do some changes in x64.inc, see below - but
> as far as I know, that should work - and it does, for all kinds of
> calls, except calling constructors on Components.
> Scripts like the following will crash the Program with a SIGSEGV.
>
> |program Script;
> var
>   f:TForm;
>   b:TButton;
> begin
>   f:=TForm.CreateNew(nil); //<- Works
>   b:=TButton.Create(f); //<- crash
>   b.Parent:=f;
>   f.Show;
> end.|
>
>
> Crash in the Program is here:
>
> |CLASSES_TCOMPONENT_$__INSERTCOMPONENT$TCOMPONENT
> 000000000044F900 4883ec38                 sub    $0x38,%rsp
> 000000000044F904 48895c2420               mov    %rbx,0x20(%rsp)
> 000000000044F909 4889742428               mov    %rsi,0x28(%rsp)
> 000000000044F90E 4889cb                   mov    %rcx,%rbx
> 000000000044F911 4889d6                   mov    %rdx,%rsi
> 000000000044F914 4889da                   mov    %rbx,%rdx
> 000000000044F917 4889f1                   mov    %rsi,%rcx
> 000000000044F91A 4889f0                   mov    %rsi,%rax
> 000000000044F91D 488b00                   mov    (%rax),%rax
> 000000000044F920 ff9068010000             callq  *0x168(%rax)  <-- crash|
>
>
> The same Script runs fine when the Application was compiled with x86
> Lazarus 1.0. By the way: creating a TObject with e.g. o:=TObject.Create
> doesn't break at al.
>
> Interestingly (and that is how I came to ask about the calling
> conventions), when I start debugging
> <SomeClass>.Create(aOwner:TComponent)-Type of Constructors, there is
> some difference in the Register values, depending on whether the
> Constructor was called from "pure" FPC-Code or the Script (at least so
> it seems):
>
> o Called from FPC: rcx: 0 (nil), rdx: Class Reference, r8: Value of aOwner
> o Called from Script: rcx: Class Reference, rdx: 1 (!?), r8: Value of
> aOwner (at least so it seems)


You need to adapt PascalScript appropriately then: probably similiar
code to x86.inc:534+ needs to be added to x64.inc around 582.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Question on Calling Conventions (for: PascalScript on Win x64)

Alexander Hofmann
Am 05.09.2012 20:18, schrieb Florian Klämpfl:
> Am 05.09.2012 18:27, schrieb Alexander Hofmann:
> o Called from FPC: rcx: 0 (nil), rdx: Class Reference, r8: Value of
> aOwner o Called from Script: rcx: Class Reference, rdx: 1 (!?), r8:
> Value of aOwner (at least so it seems)
>
> You need to adapt PascalScript appropriately then: probably similiar
> code to x86.inc:534+ needs to be added to x64.inc around 582.
>
>
You were right of course! I could have sweared I looked over the
differences of x86 and x64 numerous times, but.. .well.

After some copy'n'paste it work's like a charm. Seems The only
difference is in calling Virtual Constructors (it might not be the best
looking code, I could have omitted the Variable, but... well.)

Thanks for the hint!

By the way, it was possible to implement calling of Methods from within
the script, too. It seems as if FPC on x64 would paste Object's Methods
in one Register - as a Pointer to a "Record" containing references to
code and "self"? At least it worked out for me that way..


The diff is a bit longer; so I didn't want to paste it here, instead
it's here (in case someone's interested): http://pastebin.com/c8A81kju
Below is just the change for Virtual constructors:

Index: x64.inc
===================================================================
--- x64.inc    (revision 38441)
+++ x64.inc    (working copy)
@@ -14,7 +14,7 @@
   _RCX, _RDX, _R8, _R9: IPointer;
   var _XMM0: Double;
   _XMM1, _XMM2, _XMM3: Double;
-  aStack: Pointer; aItems: IntPtr); assembler; {$IFDEF
FPC}nostackframe;{$ENDIF}
+  aStack: Pointer; aItems: PtrUInt); assembler; {$IFDEF
FPC}nostackframe;{$ENDIF}
 asm
 (* Registers:
     RCX: Address
@@ -37,7 +37,7 @@
   mov rdx, aStack
   jmp @compareitems
 @work:
-  push [rdx]
+  push qword ptr [rdx]
   dec rcx
   sub rdx,8
 @compareitems:
@@ -280,6 +280,9 @@
   CallData: TPSList;
   I: Integer;
   pp: ^Byte;
+{$IFDEF FPC}
+  IsVirtualCons: Boolean;
+{$ENDIF}
 
   function rp(p: PPSVariantIFC): PPSVariantIFC;
   begin
@@ -579,6 +582,18 @@
 {$ENDIF}
     _RAX := 0;
     RegUsage := 0;
+    {$IFDEF FPC}
+    // FIX FOR FPC constructor calls
+    if (Integer(CallingConv) and 128) <> 0 then begin
+      IsVirtualCons := true;
+    end else
+      IsVirtualCons:= false;
+    if IsVirtualCons then begin
+      if not GetPtr(rp(Params[0])) then exit; // this goes first
+      StoreReg(IPointer(_Self));
+      Params.Delete(0);
+    end else
+    {$ENDIF}
     if assigned(_Self) then begin
       StoreReg(IPointer(_Self));
     end;



_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

signature.asc (265 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Question on Calling Conventions (for: PascalScript on Win x64)

Martin Frb
On 06/09/2012 01:28, Alexander Hofmann wrote:
> You were right of course! I could have sweared I looked over the
> differences of x86 and x64 numerous times, but.. .well.
>
> After some copy'n'paste it work's like a charm. Seems The only
> difference is in calling Virtual Constructors (it might not be the best
> looking code, I could have omitted the Variable, but... well.)
>

I don't know if this is monitored:
https://github.com/remobjects/pascalscript/issues
or if there are other means of contact.

But maybe this can be sent to them?
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Question on Calling Conventions (for: PascalScript on Win x64)

Carlo Kok-2
Op 6-9-2012 02:43, Martin schreef:

> On 06/09/2012 01:28, Alexander Hofmann wrote:
>> You were right of course! I could have sweared I looked over the
>> differences of x86 and x64 numerous times, but.. .well.
>>
>> After some copy'n'paste it work's like a charm. Seems The only
>> difference is in calling Virtual Constructors (it might not be the best
>> looking code, I could have omitted the Variable, but... well.)
>>
>
> I don't know if this is monitored:
> https://github.com/remobjects/pascalscript/issues
> or if there are other means of contact.
>
> But maybe this can be sent to them?

That'd be great. I do monitor that github repo.


Carlo Kok
RemObjects Software
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Question on Calling Conventions (for: PascalScript on Win x64)

Alexander Hofmann
Am 06.09.2012 09:27, schrieb Carlo Kok:

> Op 6-9-2012 02:43, Martin schreef:
>> On 06/09/2012 01:28, Alexander Hofmann wrote:
>>> You were right of course! I could have sweared I looked over the
>>> differences of x86 and x64 numerous times, but.. .well.
>>>
>>> After some copy'n'paste it work's like a charm. Seems The only
>>> difference is in calling Virtual Constructors (it might not be the best
>>> looking code, I could have omitted the Variable, but... well.)
>>>
>>
>> I don't know if this is monitored:
>> https://github.com/remobjects/pascalscript/issues
>> or if there are other means of contact.
>>
>> But maybe this can be sent to them?
>
> That'd be great. I do monitor that github repo.
>
Just posted.

Thanks again for the help!


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

signature.asc (265 bytes) Download Attachment