Crash using asBEHAVE_IMPLICIT_VALUE_CAST

Started by
6 comments, last by jrick 11 years, 1 month ago
Hi,

I got a problem with implicit value cast.

I register things like that :
template<class T>
class Param {
public:
  Param(const T _value) : value_(_value), ref_count_(1) { };

  T v() { return value_; } const

  int add_ref() { return ++ref_count_; }
  int release() { if( --ref_count_ == 0 ) { delete this; return 0; } return ref_count_;}

private:
  T value_;
  int ref_count_;
};

template<class T>
static Param<T> * Param_Factory(const double) {
  return new Param<T>(double);
}

void myFunction(const double d) {
}

engine->RegisterObjectType("Pdouble", 0, asOBJ_REF);
engine->RegisterObjectBehaviour("Pdouble", asBEHAVE_FACTORY, "Pdouble @f(double)", asFUNCTIONPR(Param_Factory<double>, (), Param<double> *), asCALL_CDECL);
engine->RegisterObjectBehaviour("Pdouble", asBEHAVE_ADDREF,  "void f()", asMETHOD(Param<double>, add_ref), asCALL_THISCALL);
engine->RegisterObjectBehaviour("Pdouble", asBEHAVE_RELEASE, "void f()", asMETHOD(Param<double>, release), asCALL_THISCALL);

engine->RegisterObjectBehaviour("Pdouble", asBEHAVE_IMPLICIT_VALUE_CAST, "double f() const", asMETHOD(Param<double>, v), asCALL_THISCALL);

engine->RegisterGlobalFunction("void myFunction(const double)", asFUNCTIONPR(myFunction, (const double), void), asCALL_CDECL);

if I do an implicit cast like this :
Pdouble myValue( 0.3 );
double temp = myValue;   // <-- Implicit cast
myFunction( temp );

it works ok, but if I do an implicit cast in the function call like that :
Pdouble myValue( 0.3 );
myFunction( myValue );   // <-- Implicit cast
angelscript crashes with an illegal memory access.

Is there anything wrong in my code or is implicit value cast not supposed to work when calling a function ?
Advertisement

I don't see anything wrong with your code.

It looks to be a bug in the AngelScript compiler. I'll look into 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

Unfortunately I wasn't able to reproduce the problem you reported.

After fixing a couple of minor compiler errors in the code you posted (e.g. missing arg list in asFUNCTIONPR, and missing argument in Param_Factory) I tested both scripts without any error.

Are you reproducing the crash with these small script snippets? Or does your real script perhaps have a slightly more complex expression in which the implicit cast is performed?

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

My full script is like that :


Pdouble myValue(0.3);

void setup()
{
// double temp = myValue;
myFunction(myValue);
}

void update()
{
}

My C++ code is much bigger than the code snippet I provided in my post.

I will test the script in a simpler program to see if I still reproduce the problem.

Ok, so myValue is actually a global variable. I'll see if I can reproduce the problem like this.

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

FYI, I reproduced the problem with this program :


 
#include <Windows.h>
#include "angelscript.h"
#include <stdio.h>
 
using namespace std;
 
void cb(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);
}
 
 
 
const char mscript[] = "Pdouble myValue(0.3);\n"
"\n"
"void setup()\n"
"{\n"
"// double temp = myValue;\n"
"  myFunction(myValue);\n"
"}\n"
"\n"
"void update()\n"
"{\n"
"}\n"
"\n";
 
template<class T>
class Param {
public:
  Param(const T _value) : value_(_value), ref_count_(1) { };
 
  T v() { return value_; } const
 
  int add_ref() { return ++ref_count_; }
  int release() { if( --ref_count_ == 0 ) { delete this; return 0; } return ref_count_;}
 
private:
  T value_;
  int ref_count_;
};
 
template<class T>
static Param<T> * Param_Factory(const T _value) {
  return new Param<T>(_value);
}
 
void myFunction(const double d) {
}
 
 
int main() {
 
    asIScriptEngine *ng = asCreateScriptEngine(ANGELSCRIPT_VERSION);
 
    int r;
 
    r = ng->SetMessageCallback(asFUNCTION(cb), 0, asCALL_CDECL);
    if (r < 0) printf("error %d\n", r);
 
 
  r = ng->RegisterObjectType("Pdouble", 0, asOBJ_REF);
    if (r < 0) printf("error %d\n", r);
  r = ng->RegisterObjectBehaviour("Pdouble", asBEHAVE_FACTORY, "Pdouble @f(const double)", asFUNCTIONPR(Param_Factory<double>, (const double), Param<double> *), asCALL_CDECL);
    if (r < 0) printf("error %d\n", r);
  r = ng->RegisterObjectBehaviour("Pdouble", asBEHAVE_ADDREF,  "void f()", asMETHOD(Param<double>, add_ref), asCALL_THISCALL);
    if (r < 0) printf("error %d\n", r);
  r = ng->RegisterObjectBehaviour("Pdouble", asBEHAVE_RELEASE, "void f()", asMETHOD(Param<double>, release), asCALL_THISCALL);
    if (r < 0) printf("error %d\n", r);
  r = ng->RegisterObjectBehaviour("Pdouble", asBEHAVE_IMPLICIT_VALUE_CAST, "double f() const", asMETHOD(Param<double>, v), asCALL_THISCALL);
    if (r < 0) printf("error %d\n", r);
  r = ng->RegisterGlobalFunction("void myFunction(const double)", asFUNCTIONPR(myFunction, (const double), void), asCALL_CDECL);
    if (r < 0) printf("error %d\n", r);
 
    // build
    asIScriptModule *mod = ng->GetModule("moi", asGM_ALWAYS_CREATE);
    mod->AddScriptSection("joo", mscript);
 
    r = mod->Build();
    if (r < 0) printf("error %d\n", r);
 
    // execute
    asIScriptFunction *f = mod->GetFunctionByDecl("void setup()");
    if (!f)
        return 1;
 
    asIScriptContext *ctx = ng->CreateContext();
    ctx->Prepare(f);
    r = ctx->Execute();
    if (r < 0) printf("error %d\n", r);
 
    ng->Release();
 
    return 0;
}

I've fixed the problem in revision 1584.

The compiler was producing an invalid bytecode sequence when doing the implicit cast of the global variable in preparation for the function argument.

Thanks,

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 tried the fix. My script is running ok now.

Thank you very much.

This topic is closed to new replies.

Advertisement