Conditional expression
Damn. My current project isn't actually using AS (yet), but I distinctly remember scratching my head over something similar a while ago. Any chance this same aliasing issue would have effected globals declared in the script? The bug still exists in my wrapper library, but I had been doing some crazy stuff C++ really wasn't designed for and had assumed it was my own damn fault. I was also never able to reproduce it reliably - but it was the same basic bug. I would set a global, which happened to be a boolean, through one of those getglobalxxx functions, but the value would be randomized when the script actually ran later.
Yeah, I currently have two separate bug reports on boolean variables (though the more information I get on them the more I think they are the same). Unfortunately I have yet to reproduce either of them so I will not be able to confirm if midnite's changes fixes those or not.
It could be that this problem doesn't happen with MSVC6 that I'm using on the current computer I'm at. I'll give MSVC7.1 a try later to see if the problem is reproduced on that one. If not I'll install MSVC8.0 as well, when I get the time.
I'm still investigating though, and I'll look closely at the changes midnite sent me to see if they are related to the described bug.
Regards,
Andreas
It could be that this problem doesn't happen with MSVC6 that I'm using on the current computer I'm at. I'll give MSVC7.1 a try later to see if the problem is reproduced on that one. If not I'll install MSVC8.0 as well, when I get the time.
I'm still investigating though, and I'll look closely at the changes midnite sent me to see if they are related to the described bug.
Regards,
Andreas
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
I use MSVC8 for PC and GCC for PS3/PPC64. I got the bugs, that I fixed, to happen only when compiling with GCC, when the optimization level was -O2 or higher. I never got this to occur in Visual Studio, but that doesn't mean much.
To explain in detail what I got to happen (so you know why I made the changes I did, since your compiler isn't generating the same code) I'll explain.
The bugs I were seeing were visible in the unit tests for test_return and test_optimization.
In test_return, while the system function returned true (0x01), when that value was getting saved to the context's register1 (as_callfunc_ppc.cpp), register1 was first completely zero'd out, then the return byte was saved at the first byte of register1. When the optimizer optimized this, it ended up rearranging the instructions so that the writing of the return byte was done before the register was zero'd out. This always made the return 0. This was fixed by only zeroing out the bytes not affected by where the return value was going to be stored.
In test_optimization, it worked fine until the tests that did something like:
"bool a = true, b = false; boolValue = a or b;"
boolValue was always coming back set to false. The problem in this case was in the bytecode execution (as_context.cpp). The opcodes that would read a dword from a space in memory (or register1) and then zero the memory and then write some sort of result back (such as BC_TZ, etc.) to the same memory. In this case, the optimizer would again rearrange the reads and writes just as above.
There was a third case of this happening in the actual bytecode generation (as_bytecode.cpp). For the opcode instructions that had a byte or word argument InstrSHORT_B or InstrSHORT_W, "last->arg" was first zero'd out then written to with the proper value. Once again the optimizer rearranged the instructions to 0 out after it wrote the proper value. This made some of my (word or byte) constants end up being zero when the code was executed.
The common thread for all these bugs was "zeroing out a piece of memory before writing the proper value to it". You'd really think that the optimizer wouldn't be so cruel, but apparently GCC feels it's ok to reorder those writes.
To explain in detail what I got to happen (so you know why I made the changes I did, since your compiler isn't generating the same code) I'll explain.
The bugs I were seeing were visible in the unit tests for test_return and test_optimization.
In test_return, while the system function returned true (0x01), when that value was getting saved to the context's register1 (as_callfunc_ppc.cpp), register1 was first completely zero'd out, then the return byte was saved at the first byte of register1. When the optimizer optimized this, it ended up rearranging the instructions so that the writing of the return byte was done before the register was zero'd out. This always made the return 0. This was fixed by only zeroing out the bytes not affected by where the return value was going to be stored.
In test_optimization, it worked fine until the tests that did something like:
"bool a = true, b = false; boolValue = a or b;"
boolValue was always coming back set to false. The problem in this case was in the bytecode execution (as_context.cpp). The opcodes that would read a dword from a space in memory (or register1) and then zero the memory and then write some sort of result back (such as BC_TZ, etc.) to the same memory. In this case, the optimizer would again rearrange the reads and writes just as above.
There was a third case of this happening in the actual bytecode generation (as_bytecode.cpp). For the opcode instructions that had a byte or word argument InstrSHORT_B or InstrSHORT_W, "last->arg" was first zero'd out then written to with the proper value. Once again the optimizer rearranged the instructions to 0 out after it wrote the proper value. This made some of my (word or byte) constants end up being zero when the code was executed.
The common thread for all these bugs was "zeroing out a piece of memory before writing the proper value to it". You'd really think that the optimizer wouldn't be so cruel, but apparently GCC feels it's ok to reorder those writes.
Quote: Original post by midnite
I use MSVC8 for PC and GCC for PS3/PPC64. I got the bugs, that I fixed, to happen only when compiling with GCC, when the optimization level was -O2 or higher. I never got this to occur in Visual Studio, but that doesn't mean much.
Strict aliasing optimizations are enabled by default in GCC and disabled by default in Visual Studio.
midnite:
I didn't know the compilers were doing destructive optimizations like this. But with this knowledge your solution makes sense.
It sounds like it really could be what the other guys have been seeing.
Thanks a lot for your help, I wouldn't have found that problem myself.
Regards,
Andreas
I didn't know the compilers were doing destructive optimizations like this. But with this knowledge your solution makes sense.
It sounds like it really could be what the other guys have been seeing.
Thanks a lot for your help, I wouldn't have found that problem myself.
Regards,
Andreas
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
I've committed to the SVN part of the changes that midnite sent me. If he's right and this is related to your problem, you should now be able to use the boolean values again (as of revision 126 in the SVN).
mono2k, would you mind giving revision 126 a try and telling me if the problem with the booleans still persists or not?
mono2k, would you mind giving revision 126 a try and telling me if the problem with the booleans still persists or not?
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
I tried again to reproduce my own problem, and I still couldn't. None of the test cases I've tried have the same behavior. I can let you know if this fixes if I ever get around to updating the version of angelscript in that project again.
Sorry, I was away from my computer.
I've inserted the test above in the beginning of my project and it works nice. I'm a bit confused, since the example shares the same logic with my own project. I've double checked my own code but it doesn't contain any complicated boolean expressions and int32 works nice where boolean fails. I'll try svn version later today or maybe tomorrow.
I've inserted the test above in the beginning of my project and it works nice. I'm a bit confused, since the example shares the same logic with my own project. I've double checked my own code but it doesn't contain any complicated boolean expressions and int32 works nice where boolean fails. I'll try svn version later today or maybe tomorrow.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement