Jump to content

  • Log In with Google      Sign In   
  • Create Account


- - - - -

Using global funcdef setter with imported function gives assert or invalid bytecode

  • You cannot reply to this topic
1 reply to this topic

#1 Wipe   Members   -  Reputation: 244

Like
0Likes
Like

Posted 11 June 2014 - 06:03 AM

I have this small piece of code
#include "utils.h"

const bool fail = true;

/*/ global funcdef var (setter) + imports /*/

const char* funcdef_import_assert_as =
"import void bar() from \"somewhere\";"
"void test1(){ @foo = test2; }"
"void test2(){ @foo = bar;   }"; // the problem

void set_funcdef_var(asIScriptFunction*) {}

bool funcdef_import_assert()
{
    COutStream cout;
    asIScriptEngine* engine = asCreateScriptEngine( ANGELSCRIPT_VERSION );
    engine->SetMessageCallback( asMETHOD(COutStream,Callback), &cout, asCALL_THISCALL );

    engine->RegisterFuncdef( "void MyVoid()" );
    engine->RegisterGlobalFunction( "void set_foo(MyVoid@)", asFUNCTION(set_funcdef_var), asCALL_CDECL );

    int r;
    asIScriptModule* module = engine->GetModule( "script", asGM_ALWAYS_CREATE );
    module->AddScriptSection( "script", funcdef_import_assert_as );

    if( module->Build() < 0 ) // assert (-DNDEBUG not present)
    {
	 PRINTF( "script1 Build fail\n" );
	 return( fail );
    }

    CBytecodeStream bytecode("");
    if( module->SaveByteCode( &bytecode ) < 0 )
    {
	 PRINTF( "bytecode save fail\n" );
   	 return( fail );
    }

    asIScriptModule* module_bytecode = engine->GetModule( "script_bytecode", asGM_ALWAYS_CREATE );
    if( module_bytecode->LoadByteCode( &bytecode ) < 0 ) // error (-DNDEBUG present)
    {
	PRINTF( "bytecode load fail\n" );
	 return( fail );
    }

    engine->Release();
    return( !fail );
}
Angelscript compiled with NDEBUG (my setup)
(0, 0) : Error   : LoadByteCode failed. The bytecode is invalid. Number of bytes read from stream: 187
Angelscript compiled without NDEBUG
testgnuc: ../../source/as_scriptfunction.cpp:468: virtual int asCScriptFunction::AddRef() const: Assertion `funcType != asFUNC_IMPORTED' failed.
-------------------------------------------------------


And related question:
Is such code the correct way of handling global funcdefs with configuration as above? I have a feeling that blindly calling Release() without AddRef() will lead me into trouble some sunny day (yet i need it or garbare collector will complain when releasing engine).
 
vector<asUINT> Script::Config::runFunctions;

/// called when changing script function used for loop(), draw(), etc.
void Script::Config::ChangeRunFunction( asUINT type, asIScriptFunction* func )
{
    asIScriptContext* ctx = asGetActiveContext();
    if( !ctx )
        return;

    asIScriptEngine* engine = ctx->GetEngine();
    if( !engine )
        return;

    asUINT oldFuncId = runFunctions[type];
    asIScriptFunction* oldFunc = engine->GetFunctionById( oldFuncId );
    if( oldFunc )
        oldFunc->Release();

    int funcId = 0;
    if( func )
        funcId = func->GetId();

    runFunctions[type] = funcId;
}

/// called before releasing engine
void Script::Config::Finish( asIScriptEngine* engine )
{
    for( auto funcId : runFunctions )
    {
        if( !funcId )
            continue;

        asIScriptFunction* func = engine->GetFunctionById( funcId );
        if( func )
            func->Release();
    }
}

Edited by Wipe, 11 June 2014 - 07:58 AM.


Sponsor:

#2 Andreas Jonsson   Moderators   -  Reputation: 3226

Like
0Likes
Like

Posted 11 June 2014 - 07:28 AM

Hmm, this is not something I had considered before (taking the address of imported functions).

 

It looks like this is currently broken in the code, but I should be able to have it fixed without too much trouble.

 

I'll look into it and let you know as soon as I have an update.

 

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





PARTNERS