RegisterGlobalFunction returns asNOT_SUPPORTED with AS_MAX_PORTABILITY

Started by
6 comments, last by zppz 7 years, 1 month ago

Hello! Thanks for all your work on Angelscript and the support here!

I am having trouble updating from 2.25.2 to 2.31.2 (yes, a long break). In my program code it was mostly just a case of replacing asIObjectType with asITypeInfo, but I also had some unexpected problems with building Angelscript itself.

On Linux and Windows I had to define __STDC_LIMIT_MACROS to avoid a problem with UINT64_MAX being undefined (Mac seems to be ok without this change).

Further, for Windows (mingw32 cross-compiling on Linux) I had a strange compile error from as_callfunc_x86.cpp:

{standard input}: Assembler messages:
{standard input}:86: Error: CFI instruction used without previous .cfi_startproc
{standard input}:87: Error: CFI instruction used without previous .cfi_startproc
(... and so on for about 50 lines like this)

I found I could avoid that by defining AS_MAX_PORTABILITY but then I get runtime problems, when my program starts up I want to register some global functions like this:

scriptEngine->RegisterGlobalFunction("float rnd()", asFUNCTION(rnd), asCALL_CDECL);

... which returns asNOT_SUPPORTED.

On native Windows (again mingw32 but of course not cross-compiled) I do not need to define AS_MAX_PORTABILITY and all is ok without it. But if I define it I get the same problem so it looks like I just need to avoid it if I can. So I guess the question is, how can I get around that "CFI instruction used..." error without using AS_MAX_PORTABILITY?

If it helps, I'm running on Fedora15 x64 and the mingw32 cross-compiler I'm using is pretty standard, I just did "yum install mingw32*" to have the package manager install everything. I'm using cmake to compile, I only changed one line in CMakeLists.txt to add the two defines I mentioned above:

add_definitions(-DANGELSCRIPT_EXPORT -D_LIB -D__STDC_LIMIT_MACROS -DAS_MAX_PORTABILITY)

Then I just build like this:

mingw32-cmake .
mingw32-make
Advertisement

On Linux and Windows I had to define __STDC_LIMIT_MACROS to avoid a problem with UINT64_MAX being undefined (Mac seems to be ok without this change).

Unfortunately the UINT64_MAX macro I used to fix a previous bug wasn't very cross-platform friendly. I've since replaced the use of UINT64_MAX with my own constant in the 2.32.0 WIP version so this problem shouldn't happen in future releases.

I found I could avoid that by defining AS_MAX_PORTABILITY but then I get runtime problems, when my program starts up I want to register some global functions like this:

By defining AS_MAX_PORTABILITY you are disabling all assembler code in the library and will only be able to use the generic calling convention when registering the application interface. Since your code is using native calling conventions you get the asNOT_SUPPORTED error.

Windows (mingw32 cross-compiling on Linux)

mingw cross-compiling on Linux for Windows should produce exactly the same result as compiling with mingw locally on Windows. It would appear that while cross compiling mingw is not getting the correct compiler definitions (predefined macros) so the as_config.h isn't able to properly detect which part of the code in as_callfunc_x86.cpp should be compiled.

Can you take a look at the set of predefined macros provided by mingw when cross compiling and when compiling locally on Windows? Specifically look for differences. Based on the differences, the code in as_config.h probably needs to be adjusted to make sure the cross compilation gets the exact same defines set as when compiling locally.

With gnuc you can get the list of predefined macros with the following command:

echo . | g++ -dM -E -

I believe he same is possible on mingw, though you'll have to use the appropriate command line tool and provide all the command line arguments you use when compiling normally.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Thanks for the tips. Here are the differences between the defines as given by that command you mentioned:

Defined in cross-compiler but not native
#define __pentiumpro__ 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
#define __GNUC_PATCHLEVEL__ 3
#define __i686 1
#define __USING_SJLJ_EXCEPTIONS__ 1
#define __i686__ 1
#define __VERSION__ "4.5.3 20110428 (Fedora MinGW 4.5.3-1.fc15)"
#define __pentiumpro 1
#define __GNUC_MINOR__ 5
Defined in native but not cross-compiler:
#define __ORDER_LITTLE_ENDIAN__ 1234
#define __GNUC_PATCHLEVEL__ 2
#define _thiscall __attribute__((__thiscall__))
#define __GCC_HAVE_DWARF2_CFI_ASM 1
#define __tune_i386__ 1
#define __DECIMAL_BID_FORMAT__ 1
#define __VERSION__ "4.6.2"
#define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __ORDER_PDP_ENDIAN__ 3412
#define __thiscall __attribute__((__thiscall__))
#define __DBL_DECIMAL_DIG__ 17
#define __ORDER_BIG_ENDIAN__ 4321
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __GNUC_MINOR__ 6
#define __FLT_DECIMAL_DIG__ 9
I tried compiling past releases to see where the problem first shows up, it's between 2.30.2 and 2.31.0.
In the as_callfunc_x86.cpp file of 2.31.0 some assembler within ifdef __OPTIMIZE__ sections has been modified, and moved from the end of the functions to the beginning, eg:
I have no idea what the assembler is doing, but I just reverted this change back to how it was in 2.30.2 and I can build and run ok with the cross-compiler.
So my problem is dealt with now, but let me know if I can try anything else on the cross-compiler if it helps.

The change you're referring to was done in revisions 2282 and 2283. It was done to fix crashes that would occur if the application code threw an exception and the AngelScript library had been compiled with optimizations turned on.

Just undoing the change is probably not the correct move, as you would expose yourself to the potential crash (unless you are certain your application code doesn't throw any exceptions).

I think the compiler definition __GCC_HAVE_DWARF2_CFI_ASM that is there in the native compilation but not in the cross compilation may be the key to the correct solution.

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 did a little bit of googling on this. And found the following pages of interest:

http://www.manpagez.com/man/1/gcc/

https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html

Try adding the command line argument -gdwarf to the cross-compiler. Hopefully it should fix the problem without reverting the code changes in as_callfunc_x86.cpp.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

cc1plus: error: unrecognised debug output level "dwarf"

But looking through the man pages I just happened to notice this one, which lets me compile and run ok:

-fno-dwarf2-cfi-asm

"Emit DWARF unwind info as compiler generated .eh_frame section instead of using GAS .cfi_* directives."

Alright. So everything is working fine now?

I'll add a note about this in the manual in case anyone else runs in to the same problem.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Yes, I'm ok now :) Thanks for your help.

This topic is closed to new replies.

Advertisement