Advertisement

Angelscript on Raspberry Pi

Started by November 10, 2012 01:31 AM
130 comments, last by WitchLord 11 years, 10 months ago

What is the COMPLEX_RETURN_MASK defined as? It is defined in as_config.h.

If you haven't made any changes to the as_config.h with regards to this define, it is defined as asOBJ_APP_CLASS_DESTRUCTOR. But to be consistent with other gcc targets it should probably be defined as:

#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)

Still, if this flag was incorrectly defined, you would have gotten errors in testcdecl_class_k.cpp, which I assume you didn't.

I think it's best if you disassemble the operator* so we can see how the type really should be returned before you make any changes.

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 haven´t made any changes regarding to this define.

in as_config.h COMPLEX_RETURN_MASK is defined as (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT). I´ll disassemble operator* and post the results ASAP.

Advertisement

Ok, finally found time for some disassembling. First the code I used:


#include <iostream>
#include <string>
#include <math.h>

typedef unsigned long asDWORD;

struct Vector3
{
Vector3();
Vector3(const Vector3 &other);
Vector3(float x, float y, float z);


float length() const;

friend Vector3 operator*(float s, const Vector3 &v);
friend Vector3 operator*(const Vector3 &v, float s);

float x;
float y;
float z;
};


Vector3::Vector3()
{
x = 0;
y = 0;
z = 0;
}

Vector3::Vector3(const Vector3 &other)
{
x = other.x;
y = other.y;
z = other.z;
}

Vector3::Vector3(float _x, float _y, float _z)
{
x = _x;
y = _y;
z = _z;
}

float Vector3::length() const
{
return sqrtf(x*x + y*y + z*z);
}

Vector3 operator*(float s, const Vector3 &v)
{
// Return a new object as a script handle
Vector3 res(v.x * s, v.y * s, v.z * s);
return res;
}

Vector3 operator*(const Vector3 &v, float s)
{
// Return a new object as a script handle
Vector3 res(v.x * s, v.y * s, v.z * s);
return res;
}

int main()
{
Vector3 v(1,0,0);
bool x = false;

if ( (v * 2).length() == 2)
x = true;

std::cout << "El resultado de length() == 2 es " << x << "\n";
}

And the disassemblies:

main:

0x88a8 push {r11, lr}
0x88ac add r11, sp, #4
0x88b0 sub sp, sp, #32
0x88b4 sub r3, r11, #32
0x88b8 mov r0, r3
0x88bc vldr s0, [pc, #164] ; 0x8968 <main()+192>
0x88c0 vldr s1, [pc, #164] ; 0x896c <main()+196>
0x88c4 vldr s2, [pc, #160] ; 0x896c <main()+196>
0x88c8 bl 0x8718 <Vector3::Vector3(float, float, float)>
0x88cc mov r3, #0
0x88d0 strb r3, [r11, #-5]
0x88d4 sub r2, r11, #20
0x88d8 sub r3, r11, #32
0x88dc mov r0, r2
0x88e0 mov r1, r3
0x88e4 vldr s0, [pc, #132] ; 0x8970 <main()+200>
0x88e8 bl 0x8840 <operator*(Vector3 const&, float)>
0x88ec sub r3, r11, #20
0x88f0 mov r0, r3
0x88f4 bl 0x876c <Vector3::length() const>
0x88f8 vmov.f32 s14, s0
0x88fc vldr s15, [pc, #108] ; 0x8970 <main()+200>
0x8900 vcmp.f32 s14, s15
0x8904 vmrs APSR_nzcv, fpscr
0x8908 movne r3, #0
0x890c moveq r3, #1
0x8910 uxtb r3, r3
0x8914 cmp r3, #0
0x8918 beq 0x8924 <main()+124>
0x891c mov r3, #1
0x8920 strb r3, [r11, #-5]
0x8924 ldr r0, [pc, #72] ; 0x8974 <main()+204>
0x8928 ldr r1, [pc, #72] ; 0x8978 <main()+208>
0x892c bl 0x85a4 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8930 mov r3, r0
0x8934 mov r2, r3
0x8938 ldrb r3, [r11, #-5]
0x893c mov r0, r2
0x8940 mov r1, r3
0x8944 bl 0x85b0 <std::ostream::operator<<(bool)>
0x8948 mov r3, r0
0x894c mov r0, r3
0x8950 ldr r1, [pc, #36] ; 0x897c <main()+212>
0x8954 bl 0x85a4 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8958 mov r3, #0
0x895c mov r0, r3
0x8960 sub sp, r11, #4
0x8964 pop {r11, pc}
0x8968 svccc 0x00800000
0x896c andeq r0, r0, r0
0x8970 andmi r0, r0, r0
0x8974 andeq r0, r1, r8, lsl r12
0x8978 andeq r8, r0, r0, ror r10
0x897c muleq r0, r4, r10

operator*:


0x8840 push {r11, lr}
0x8844 add r11, sp, #4
0x8848 sub sp, sp, #16
0x884c str r0, [r11, #-8]
0x8850 str r1, [r11, #-12]
0x8854 vstr s0, [r11, #-16]
0x8858 ldr r3, [r11, #-12]
0x885c vldr s14, [r3]
0x8860 vldr s15, [r11, #-16]
0x8864 vmul.f32 s13, s14, s15
0x8868 ldr r3, [r11, #-12]
0x886c vldr s14, [r3, #4]
0x8870 vldr s15, [r11, #-16]
0x8874 vmul.f32 s14, s14, s15
0x8878 ldr r3, [r11, #-12]
0x887c vldr s12, [r3, #8]
0x8880 vldr s15, [r11, #-16]
0x8884 vmul.f32 s15, s12, s15
0x8888 ldr r0, [r11, #-8]
0x888c vmov.f32 s0, s13
0x8890 vmov.f32 s1, s14
0x8894 vmov.f32 s2, s15
0x8898 bl 0x8718 <Vector3::Vector3(float, float, float)>
0x889c ldr r0, [r11, #-8]
0x88a0 sub sp, r11, #4
0x88a4 pop {r11, pc}

I also made a mistake in checking how COMPLEX_RETURN_MASK was defined (I checked its definition under MSVC....wacko.png ). In the RPi COMPLEX_RETURN_MASK is defined as (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR).
So, does this give you any ideas on how to fix the problem with this test?
The type is clearly returned in memory, and the pointer to the memory is passed to the function in r0, the pointer to the object itself in r1, and the float value in s0.

So, Vector3::operator* should clearly be called with armFuncR0R1.

I'm pretty sure the problem is with the COMPLEX_RETURN_MASK. Despite that you say it is defined as (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR) I don't think it is. On Nov 26th you showed the defines that get configured by running 'g++ -dM -E as_config.h' (see page 3 in this thread), and there it is seen that the flag is defined as asOBJ_APP_CLASS_DESTRUCTOR.

Add the following in as_config.h in the section for gnuc, Linux, arm (somewhere around line 780):

#undef COMPLEX_RETURN_MASK
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)

I believe that will solve this test.

While you're at it you may also add the same for the COMPLEX_MASK, which really should be the same. This is similar to what is done for gnuc, Linux, x86 and gnuc, Linux, x64.


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'm pretty sure the problem is with the COMPLEX_RETURN_MASK. Despite that you say it is defined as (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR) I don't think it is. On Nov 26th you showed the defines that get configured by running 'g++ -dM -E as_config.h' (see page 3 in this thread), and there it is seen that the flag is defined as asOBJ_APP_CLASS_DESTRUCTOR.

Add the following in as_config.h in the section for gnuc, Linux, arm (somewhere around line 780):
#undef COMPLEX_RETURN_MASK
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)

I believe that will solve this test.


But we´ve already added those #undef - #define sections... check a few posts after the one you mention (november 27) and you´ll find the one in which you told me to do it. What´s more, it actually solved a bug back then.

Now... the problem might be that armFuncR0R1 hasn´t been adapted yet to the ABI... sorry aboyt that, I was assuming that operator* should be called using armFuncR0, but if it must use armFUncR0R1 then I´ll begin editing that function. I´ll be back with results.
Just as I suspected - I ported armFuncR0R1 and now it works as it should. The next error is pointing to armFuncR0ObjLast, which is the other function I hadn´t ported yet. Fixing it right now...
Advertisement
But we´ve already added those #undef - #define sections... check a few posts after the one you mention (november 27) and you´ll find the one in which you told me to do it. What´s more, it actually solved a bug back then.

You're right of course. The thread is too long to remember all that we've discussed before. ;)

I'm glad it's working now. Hopefully after you update the function armFuncR0ObjLast everything will pass successfully.

As I mentioned earlier, I'll increment the tests for the native calling convention in test_feature to cover these last scenarios better, so it will be easier for the next platform that needs to be supported.

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

Victoria!

All tests pass succesfully! There´s only one thing left that´s bothering me: after the Test_Addon_Serializer passes, I´m getting a "GC cannot free an object of type '_builtin_function_', it is kept alive by the application" message. What does it mean? Do I have to worry about it?

One more question: when passing floats, does the args array carry pointers to the floats or the actual float values? Because depending on the answer my implementation could have one tiny little flaw....dry.png

Excellent news! Congratulations on all your hard work. I know it took quite a bit of effort from your side, but I hope you've enjoyed it.

The GC error message indicates that something is wrong. Some object wasn't released as it should. I'll have to log in to do some debugging in order to find out what it is though.

The args array will contain the actual float values, unless the argument is a reference to a float of course.

Would you mind sending me the files you've modified by e-mail? I'll be going away for vacation in a soon (2nd week of January), but I'll try to find the time to merge your changes into the SVN before that.

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´ll correct the tiny little flaw and do some cleanup to the code before sending you the files - as you may have already noticed, it´s full of comments and "cout" statements and other stuff to help debugging, even in the .S file. That should give you time to log in and try to find what´s causing the GC error.

Having AS running on the RPi is going to be awesome and I´m sure many people will be atracted to it (it being both RPi and AS)!

This topic is closed to new replies.

Advertisement