Delphi XE2, TWebBrowser, float divide by zero
Asked Answered
M

1

5

In Delphi 2010 and Delphi 2007 I am using Set8087CW on WebBrowserBeforeNavigate / WebBrowserDocumentComplete to prevent FPU errors inside ActiveX to cripple my application.

But somehow this is not working in Delphi XE2, at least when in 64bit mode.

When clicking links (any) I get "float divide by zero". (The initial loading of a website address or content into TWebBrowser works fine.)

The callstack shows this to happen inside system32\D3D10Warp.dll (maybe used by IE9?) in response to TApplication.ProcessMessage (and some ??? inbetween the two)

Macarthur answered 20/2, 2012 at 9:59 Comment(9)
documentation says (docwiki.embarcadero.com/VCL/en/System.Set8087CW): Set8087CW On 64-bit Windows: This control word does not control floating-point operations, because the SSE register is used for floating point in 64-bit mode, instead of the FPU (floating-point unit). However the FPU is still present in 64-bit mode, so SGet8087CW sets the value of the control word, as in 32-bit mode.Proverbs
@teran, yeah but what is that SGet8087CW ?Ingram
@Ingram A typo for Set8087CW, copied from docwiki.embarcadero.com/VCL/en/System.Set8087CW.Waterscape
Okay, so waht this really comes down to is if IE9/64bit uses the FPU? Beause the Get8087CW call sets the FPU as always. I will try Math.SetExceptionMask (?) but if anyone has more ideas, do please let me know...Macarthur
@Macarthur There's also SetMXCSR. My suggestion would be to use both that and Set8087CW. Both 32-bit and 64-bit Windows can use FPU and SSE operations, regardless of what Delphi uses for floating point operations.Waterscape
Math.SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]) works! (I believe this call wraps both SSE and FPU depending on 32/64 bit mode. I think I will call it in addition to my old code when on 64bit) @hvd: I will investigate SetMXCSR and possibly use that instead!Macarthur
Just a side comment: do you ever restore FTP after setting it on WebBrowserBeforeNavigate?Melanoma
Yes, I used WebBrowserDocumentComplete in the past. However, that does not seem to be enough any longer, so I just changed it to immediately after creating/showing the control and before freeing/hiding the control. (Probably safer under all circumstances.)Macarthur
@Tom, sorry for the typo. I meant FPU (not FTP).Melanoma
F
10

You will need to mask SSE exceptions on 64 bit because 64 bit code typically uses SSE to perform floating point arithmetic.

Call SetMXCSR to change the control state of the SSE unit. Personally I would continue masking 8087 exceptions since 64 bit code is perfectly at liberty to use the 8087 unit should it so wish. The magic MXCSR value that you want to use when calling the web browser code is $1F80. This is the default Windows value for MXCSR.

Alternatively, you can call SetSSEExceptionMask and SetFPUExceptionMask passing exAllArithmeticExceptions to mask all exceptions. These convenience methods would make your code more readable.

If you are satisfied that you only need to mask exceptions on 8087 under x86 and SSE under x64 then you can just call SetExceptionMask. This will change the 8087 control state under x86 and change the SSE control state under x64.

If I had to choose between setting the entire control state or using the convenience methods to change just the exception masking part of the state, I would set the entire control state. These ActiveX controls are written under the assumption that you will be using MS tooling and expect a specific FP control state. I would give these controls the exact control state that they expect and then revert back to the Delphi control state when execution returns from the controls.

Fervidor answered 20/2, 2012 at 10:41 Comment(3)
Thanks for all the help everyone. I am accepting this response as the solution since it addresses the topic in-depth (and I tested using SetMXCSR directly which also seems to work. I have changed my code to use this in addition to the old code.)Macarthur
+1; thanks, do you mind if I blog about this quoting some of your answer?Slung
@JeroenWiertPluimers I most certainly do not mind in the slightest. Please be my guest.Fervidor

© 2022 - 2024 — McMap. All rights reserved.