Program shutting down if exception raised in Pascal Script for Delphi in 64-bit

Hi
We have been using Pascal Script for more than 20 years with great success.
Recently we have started providing a 64-bit version of our program. After some help from Remobjects we got Pascal Script to work on 64 bit also.

But we have a problem on 64-bit that we don’t have on 32 bit.
If the scripts generates an exception, and the same TpsScript instance is reused after to call the script again, then the program will just shut down with no error message given.
Take a look at the attached simplified project demonstrating the issue. The code should have no external requirements.
I have included in the project some options to try to get around the problem, but I am wondering if it is a problem that you are willing to fix.
Note the “Alt. 1: Recompile On Error (recompiles immediately)” option I have added does not help and still results in the program shutting down.

We are using Delphi 11.3 with all patches, and the latest Pascal Script version from your Github.

Script Exception.zip (92.9 KB)

Hi,

as a temporary workaround, you can update uPSRuntime.pas

procedure MyAllMethodsHandler;
{$ifdef CPU64}
..
asm
  PUSH RBP //<<<changed

after this any of these options works correctly on 64-bit:

  • Recompile Before Each Iteration
  • Alt. 2: Reset Compiled On Error (recompiles on next iteration)

Thanks for your reply. I did what you wrote but sadly did not make any difference.
I guess it did for you? With no other checkbox checked than “Alt. 1: Recompile On Error (recompiles immediately)”?

Just to be clear:
The workaround " * `Alt. 2: Reset Compiled On Error (recompiles on next iteration)" allready did work. And non of these workarounds are needed on 32-bit.

Hi,

hmm, in my case any option causes closing program in x64 mode. I’ve launched it without debugger.

after fix, any of these options:

  • Recompile Before Each Iteration
  • Alt. 2: Reset Compiled On Error (recompiles on next iteration)

generates

Iteration 1:
Error in SystemScript.OnCheckProduct: Division by zero
 
Iteration 2:
Error in SystemScript.OnCheckProduct: Division by zero
 
Iteration 3:
Error in SystemScript.OnCheckProduct: Division by zero
 
Iteration 4:
Error in SystemScript.OnCheckProduct: Division by zero
 
Iteration 5:
Error in SystemScript.OnCheckProduct: Division by zero
 
DONE

note: x86 uses code with STACK_BASED_EXCEPTIONS condition inside system.pas
x64 uses code inside TABLE_BASED_EXCEPTIONS condition inside system.pas.

as a result we have two different piece of code in system.pas for handling exceptions of each platform. it can be a reason why current implementation of PS works “differently” on x64 platform.

I am so sorry. I misread your first reply. I started to edit my reply, but then I saw you were allready replying again so i’ll just leave it as it was.

You are correct that any of the options you mention generates the same (correct) behaviour.
But that was also seemingly the case without your fix to uPSRuntime.

Just to be clear. In our code we have (originally) no recompiling of the script, not even after an exception, the script was always only compiled once, and it has worked as it should on 32-bit. But maybe that’s not the correct way of using TpsScript?

Hi,

it’s hard to fix original issue w/o deeply debugging that will take a lot of time.

try to create script object for each iteration like

for var I := 1 to 5 do begin
   vSystemScript := TScriptCwSystem.Create(False);

it may work correctly with precompiled script until this issue won’t fixed.

I understand that the original issue is hard to fix, but will you attempt to fix it?
I have very little knowledge of assembler programming myself.

Our real program has many places where we use Pascal script, not always via TScriptCwSystem, but always via a TScriptCw sublass. So If I need do do a workaround i probably will go for recreating TScriptCws internal TpsScript if an exception occurs. There is also performance to consider here, so i dont want to recompile more than necessary. I have made a modified version of the test program that recreates TScriptCws internal TpsScript upon errors which seems to work fine. Resetting the compiled script on the newly recreated internal TpsScript did not seem to work fine as the program then went back to shitting down again so a call to TpsScript.Compile seems needed.

The “PUSH RBP” fix you mentioned, should that be applied even if we decide to go for one of the workarounds like for instance recreating the internal TpsScript?

Hi,

yes, I’ll try to do this however I can’t say terms when it will be fixed.

yes. I’ve already added this fix to github.

1 Like

Thank you so much Evgeny. I’ll await doing any workarounds in our main program for a while and see if you figure out a fix.