Jump to content

  • Log In with Google      Sign In   
  • Create Account


- - - - -

Returning text crashes as with Mingw 4.71 but not with 4.4.1


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 Heuristics   Members   -  Reputation: 147

Like
0Likes
Like

Posted 28 March 2013 - 03:02 AM

The following is a short summary of the code that crashes angelscript in 4.7.1 but not in 4.4.1:

 

struct A {
    A() {}
    static void Constructor(A *self) {new(self) A();}
    static void Destructor(A *memory) {memory->~A();}
    std::string getText() {return this->text;}
    std::string text;
    A getA() {return A();}
};

____Code run in Angelscript____:
void main() {
    A a;
    string text = a.getA().getText();
}

 

I have appended a full runnable example below since it might just be that I am registering things in the wrong way (lets hope so).

It appears to be the case that running a function that returns text from an object that was created within angelscript causes a crash.

 


#include <angelscript.h>
#include <add_on/scriptstdstring/scriptstdstring.h>
#include <add_on/scriptbuilder/scriptbuilder.h>
#include <stdio.h>
#include <assert.h>
#include <iostream>

void MessageCallback(const asSMessageInfo *msg, void *param) {
  const char *type = "ERR ";
  if( msg->type == asMSGTYPE_WARNING )
    type = "WARN";
  else if( msg->type == asMSGTYPE_INFORMATION )
    type = "INFO";
  printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message);
}

void print(const std::string &in) {
    std::cout << in << std::endl;
}

struct A {
    A() {}
    static void Constructor(A *self) {new(self) A();}
    static void Destructor(A *memory) {memory->~A();}
    std::string getText() {return this->text;}
    std::string text;
    A getA() {return A();}
};

void registerA(asIScriptEngine *engine) {
    std::string name = "A";
    int r = engine->RegisterObjectType(name.c_str(), sizeof(A), asOBJ_VALUE | asOBJ_APP_CLASS | asOBJ_APP_CLASS_CONSTRUCTOR); assert( r >= 0 );
    r = engine->RegisterObjectBehaviour(name.c_str(), asBEHAVE_CONSTRUCT, std::string("void f()").c_str(), asFUNCTION(A::Constructor), asCALL_CDECL_OBJLAST); assert( r >= 0 );
    r = engine->RegisterObjectBehaviour(name.c_str(), asBEHAVE_DESTRUCT, "void f()", asFUNCTION(A::Destructor), asCALL_CDECL_OBJLAST); assert( r >= 0 );
    r = engine->RegisterObjectMethod("A", "string getText()", asMETHOD(A,getText), asCALL_THISCALL);assert( r >= 0 );
    r = engine->RegisterObjectMethod("A", "A getA()", asMETHOD(A,getA), asCALL_THISCALL);assert( r >= 0 );
}

std::string app = "void main() {A a;string text = a.getA().getText();}";

int main() {
    asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
    int r = engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL); assert( r >= 0 );
    RegisterStdString(engine);
    r = engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_CDECL); assert( r >= 0 );

    registerA(engine);

    CScriptBuilder builder;
    r = builder.StartNewModule(engine, "MyModule"); if( r < 0 ) {printf("Unrecoverable error while starting a new module.\n");return 0;}
    r = builder.AddSectionFromMemory("TestSection", app.c_str());if( r < 0 ) {printf("Please correct the errors in the script and try again.\n");return 0;}
    r = builder.BuildModule(); if( r < 0 ) {printf("Please correct the errors in the script and try again.\n");return 0;}

    asIScriptModule *mod = engine->GetModule("MyModule");
    asIScriptFunction *func = mod->GetFunctionByDecl("void main()"); if( func == 0 ) {printf("The script must have the function 'void main()'. Please add it and try again.\n");return 0;}
    asIScriptContext *ctx = engine->CreateContext();
    ctx->Prepare(func);
    r = ctx->Execute(); if( r != asEXECUTION_FINISHED and r == asEXECUTION_EXCEPTION) {printf("An exception '%s' occurred. Please correct the code and try again.\n", ctx->GetExceptionString());}
}

 

 



Sponsor:

#2 Andreas Jonsson   Moderators   -  Reputation: 3221

Like
0Likes
Like

Posted 28 March 2013 - 01:42 PM

Which version of AngelScript are you using? MinGW changed the ABI for native calling conventions with version 4.7. I updated AngelScript according to the new ABI only with version 2.25.1. So earlier versions of AngelScript will not work with MinGW 4.7 or later.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#3 Heuristics   Members   -  Reputation: 147

Like
0Likes
Like

Posted 28 March 2013 - 01:52 PM

I am using the latest version: 2.26.1. (I am the dude that first brought up the issue with mingw 4.7.1 behaving strangely a few months back).



#4 Andreas Jonsson   Moderators   -  Reputation: 3221

Like
0Likes
Like

Posted 28 March 2013 - 06:06 PM

Oh, I'm sorry, I checked the change list to see when exactly I had changed AngelScript. I should have noticed your name in the credit for that fix. ;)

 

Would you mind just giving the latest WIP from the svn a try? I can't be certain this problem has been fixed, but I did do some tweaks for MinGW as I was getting MinGW 64bit support up to date.

 

Let me know if it still doesn't work and I'll take a closer look on this 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

#5 Heuristics   Members   -  Reputation: 147

Like
0Likes
Like

Posted 29 March 2013 - 02:41 AM

I tried the latest svn version via sourceforge tarball download of trunk, same problem. 

 

As usual I caution that I may not be registering things properly and this might just be my fault (though i did try my best to do things correctly).



#6 Andreas Jonsson   Moderators   -  Reputation: 3221

Like
0Likes
Like

Posted 29 March 2013 - 09:52 AM

No, since it works on MinGW 4.4.1 and not MinGW 4.7.1 I think it is more likely some other difference the ABI that I didn't fix in 2.25.1.

 

I'll investigate it.


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

#7 Andreas Jonsson   Moderators   -  Reputation: 3221

Like
0Likes
Like

Posted 29 March 2013 - 01:22 PM

Well, contrary to my initial thoughts I found that it was indeed that the class A had been registered incorrectly. Even though this class doesn't have it's own destructor, copy constructor, or assignment operator it should still be registered with the flags asOBJ_APP_CLASS_CDAK. Why? Because the member 'string text' has all of these.

 

Even I wasn't aware of this, and I'll have to update the manual with this new knowledge.

 

I'm not sure why this didn't break with MinGW 4.4.1, as I don't have that version of MinGW to test with. But I did test it with MinGW 4.6.2 and it also failed in the same way as MinGW 4.7.1 so this was not related to the ABI changes that were made in MinGW 4.7.

 

The new asGetTypeTraits<type>() helper function that you helped me implement returns the correct flags.

 
int r = engine->RegisterObjectType("A", sizeof(A), asOBJ_VALUE | asGetTypeTraits<A>()); assert( r >= 0 );

Edited by Andreas Jonsson, 29 March 2013 - 01:29 PM.

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




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS