🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

angelscript and xcode 2.4

Started by
42 comments, last by urkle 17 years, 8 months ago
I guess I need to see how someone patched angel script to get it running on PPC, or maybe they were using an old version? but 2.7.0 does not want to correctly run.

as going through the main executenext function it handles the instruction different in regular code and the "Debug" code.

The main issue I'm running into right now is the PPC encodes the first 2 instruction when running the saveload test as

00 00 00 62 00 00 00 40

the INTEL encodes it as

62 00 00 00 40 00 00 00

due to Endianess

And in your debugging code you (w/ AS_DEBUG) you do
(*l_bc) & 0xFF

Which works correctly on both architectures since the value is treated as the full DWORD.

where as
*(asBYTE *)l_bc == (*l_bc) & 0xFF only in little endian systems (as you treat the l_bc array as bytes and grab the first one, which on PPC is 00)

I've changed that decoding in the switch to (*l_bc) & 0xFF, however it then blows up when fetching the WORDARG0 since you are making assumptions about the order of the data in the memory. (for the BC_PGA instruction)

When I left the instruction decoding as *(asBYTE *)l_bc and instead swapped the data in asCByteCode::Output (just the main instruction) things progressed slightly further except when it tried building the dynamic module initiated line 152 of test_saveload.cpp when it tried finding labels in asCByteCode::FindLabel as it tried finding a label w/ a number somewhere in the neighborhood of 0x30000000 (after a first calling of that function finding a label of 0x01).

Now, any assistance you can give on how things are encoded in the byte code would be helpful so I can decipher this and get it running on OS X ppc (and eventually OS X x86). I am being contracted to port a Win32 game over to Linux and Mac OS X and game author chose angelscript due to it's ease of setup and use and portability. And so far I'm impressed with the design and would rather NOT have to gut the scripting engine in this game with another and would like to try to get angelscript running on all platforms, thus adding another platform for this game that I am porting AND adding value to your great scripting language

http://www.outoforder.cc/ is my personal website (with many open source projects of my own)
http://www.frictionalgames.com/ is the home page of the game Penumbra that I am porting.

Witchlord,
Would you have some time for one on one IM/Chat sometime during the week or over the weekend that we can go over things as I decipher more of angelscript in tracking down these issues? Let me know if and when you may have time? My Timezone is at GMT-0500 (Indiana, US).

Regards,
Edward Rudd
Advertisement
What you're saying makes sense. I'm starting to think that perhaps others are not really using AngelScript on PPC after all. Maybe it's just Mac on the new Intel machines.

I'll have to review all the code that interacts with the bytecode directly to make sure they use macros that can be adapted to both little and big endian.

I think SourceForge.net has a PPC system on their compile farm, and I'll give it a try.

I don't know how much time I'll have this month for this though, as I'm currently in the middle of another project. So if you want to give it a go to get a start on it it would be great.

You'll have to start with a couple of source files:

as_bytecodedef.h - this is where the bytecodes are defined and their general structure
as_bytecode.cpp - this is where the bytecodes are constructed
as_context.cpp - this is where the bytecodes are interpreted
as_restore.cpp - this is where bytecode is saved to/loaded from disk (this is less importat to start with)

All bytecodes are packed into DWORDs. The least significant bytecode stores the instruction number. The most significant word may store a WORD argument.

A second DWORD may be used for more arguments, e.g. an additional two WORDs, or a DWORD.

Here's a table showing the layout of bytecodes (least significant byte to the right):

NO_ARG                             | | | |X|  1 DWORDW_ARG                              |a|a| |X|  1 DWORDW_W_ARG                    | | |b|b|a|a| |X|  2 DWORDsW_DW_ARG                   |b|b|b|b|a|a| |X|  2 DWORDsW_W_W_ARG                  |c|c|b|b|a|a| |X|  2 DWORDsW_W_DW_ARG         |c|c|c|c| | |b|b|a|a| |X|  3 DWORDsDW_DW_ARG          |b|b|b|b|a|a|a|a| | | |X|  3 DWORDsQW_ARG             |a|a|a|a|a|a|a|a| | | |X|  3 DWORDsW_QW_ARG           |b|b|b|b|b|b|b|b|a|a| |X|  3 DWORDsQW_DW_ARG  |b|b|b|b|a|a|a|a|a|a|a|a| | | |X|  4 DWORDs


I don't use IM. Send me an e-mail. I check it almost every hour. My timezone is GMT -0300 (Brasilia, Brazil).

I'll do my best to help you out on this problem. Penumbra is a really cool looking game, and I would be very honored if it still uses AngelScript when it gets released.

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

More exactly we need to make sure the way the bytecodes are packed in asCByteCode::Output() is the same way they are interpreted in asCContext::ExecuteNext().

I haven't done any porting between little and big endian systems before, but I guess the biggest problem is the pointer casts? I mean, shifts and bitwise-and should work just the same way independently of endianess, right?

It should be possible to rewrite the macros on lines 1080 to 1091 in as_context.cpp to be endian independent, using shifts and bitwise-and instead of pointer casts.

#define WORDARG0(x)  (*(((asWORD*)x)+1))#define WORDARG1(x)  (*(((asWORD*)x)+2))#define SWORDARG0(x) (*(((short*)x)+1))#define SWORDARG1(x) (*(((short*)x)+2))#define SWORDARG2(x) (*(((short*)x)+3))becomes#define WORDARG0(x)  (asWORD(((*x)>>16)&0xFFFF))#define WORDARG1(x)  (asWORD((*(x+1))&0xFFFF))#define SWORDARG0(x) (short(((*x)>>16)&0xFFFF))#define SWORDARG1(x) (short((*(x+1))&0xFFFF))#define SWORDARG2(x) (short(((*(x+1))>>16)&0xFFFF))

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

What I've done thus far is add some macros into as_config.h to set some ENDIAN swap macros up.
and then I've wrapped those around the appropriate pieces in the asCByteCode::Output function to encode them in the correct place. and converted ALL placed in ExecuteNext to use a consistent *(asBYTE*) cast for the instruction.

I another idea of encoding the data in a consistant way without the need for swapping bytes and shifting that I'm going to try today (for the sake of speed).

The main issue I'm having now is the FindLabel function failing.. I'm going to investigate that today as well and report back here w/ what I find.

Shifts could be different, if you're doing them with ASM instructions. The architecture might provide two different kinds of shift instructions. One that shifts bits how they actually appear in memory, and the other how they are 'logically'. The 'logical' shift should behave the same with both endians.
Quote: Original post by Deyja
Shifts could be different, if you're doing them with ASM instructions. The architecture might provide two different kinds of shift instructions. One that shifts bits how they actually appear in memory, and the other how they are 'logically'. The 'logical' shift should behave the same with both endians.


More fun:)

I opted to change the encoding function to using pointer arithmatic (my version w/o shifts/byte swapping) and it works.. Which it should as that's how the datais being decoded.

Now just stepping through the test apps and finding everywhere else where the assumption is made that the bytes are in a different order. And there are a few.. . This is going to take a while :(
I'll help you. Can you send me the code changes that you've made so far?

I was going to try compiling angelscript on sourceforge.net's PPC today, but unfortunately it seems that all three of the PPC machines are out of order at this moment :(

They have a Power5 machine as well, so I gave it a try. I'm not familiar with this CPU, but it looks to be big endian, so I might be able to do some work with it until the PPC machines are available again.

Does anyone have any idea on how to know which preprocessor macros are defined by default using gnuc? I tried:

touch test.cc
g++ -dD test.cc

But it doesn't give me any output.

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

Quote: Original post by WitchLord
I'll help you. Can you send me the code changes that you've made so far?

I was going to try compiling angelscript on sourceforge.net's PPC today, but unfortunately it seems that all three of the PPC machines are out of order at this moment :(

They have a Power5 machine as well, so I gave it a try. I'm not familiar with this CPU, but it looks to be big endian, so I might be able to do some work with it until the PPC machines are available again.

Does anyone have any idea on how to know which preprocessor macros are defined by default using gnuc? I tried:

touch test.cc
g++ -dD test.cc

But it doesn't give me any output.

Regards,
Andreas


g++ -E -dM - < /dev/null > gcc-predefines.h

That will list all the predefines to gcc-predefines.h
(I googled for that one myself many times)

unified Diff based on SVN trunk
http://www.outoforder.cc/downloads/patches/PPCFix.diff

This includes restructuring of the asCByteCode::Output, asCRestore read and write byte fixes as well as many fixes to ExecuteNext (haven't yet HIT all instructions so not everything is tested).

I also re-tested things on my x86 system to be sure things were still working the same.

I also fixed the as_debug.h so it properly declared _mkdir for GCC compilers.

Suggestion:
set the svn:eol-style property on all the source files to the value 'native', that way I won't have line ending h*** problems when I create my diffs :-D.

the callfunc_ppc function hasn't been tested AT all (obviously) and I'm currently still running in MAX_PORTABILITY mode (and DEBUG mode)

I got past the FindLabel issue (wrong encoding of instructions in ::Output)
and the SaveLoad test runs perfectly now.
TestAny, however fails miserably w/ a script assert of

--- Assert failed ---
func: void TestAny()
mdle:
sect: TestAny
line: 11
---------------------

I'm done for the night.. sleep calls me.
Am I correct that the bytecode produced by the PPC version is different from the one produce by the x86 version? Are you byteswapping during the save/restore phase so the on-disk representation is identical?
No, I have not done that yet. That is going to require a good amount of rewriting of the save/restore functions to get them to save/restore with byte swapping.

This topic is closed to new replies.

Advertisement