Jump to content
  • Advertisement
Jason Goepel

Template Factory Return Type Bug

Recommended Posts

My application is experiencing a crash in a template object's factory, because the asITypeInfo pointer being passed to the factory does not have a valid subtype. I've tried to track down the cause of this bug, and I suspect that the reference counting of template function return types may be incorrect.

When a module contains a template instantiation, function objects are added to the script engine.  Building a second module with an identical script will reuse those function objects.  After discarding the first module though, the return types of those function objects are no longer valid.  Below I have constructed a simple example which crashes due to a null engine pointer in the return type of a factory function.

class MyTmpl
{
public:
	MyTmpl(asITypeInfo *t) 
	{
		refCount = 1;
		type = t;
		OutputDebugStringA(asGetActiveContext()->GetFunction(0)->GetDeclaration());
		type->AddRef();
	}

	~MyTmpl()
	{
		if( type ) 
			type->Release();
	}

	void AddRef()
	{
		refCount++;
	}

	void Release()
	{
		if( --refCount == 0 )
			delete this;
	}

	asITypeInfo *type;
	int refCount;
};

MyTmpl *MyTmpl_factory(asITypeInfo *type)
{
	return new MyTmpl(type);
}

 

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->RegisterObjectType("MyTmpl<class T>", 0, asOBJ_REF | asOBJ_TEMPLATE);
	engine->RegisterObjectBehaviour("MyTmpl<T>", asBEHAVE_FACTORY, "MyTmpl<T> @f(int&in)", asFUNCTIONPR(MyTmpl_factory, (asITypeInfo*), MyTmpl*), asCALL_CDECL);
	engine->RegisterObjectBehaviour("MyTmpl<T>", asBEHAVE_ADDREF, "void f()", asMETHOD(MyTmpl, AddRef), asCALL_THISCALL);
	engine->RegisterObjectBehaviour("MyTmpl<T>", asBEHAVE_RELEASE, "void f()", asMETHOD(MyTmpl, Release), asCALL_THISCALL);

	asIScriptModule *mod1 = engine->GetModule("m1", asGM_ALWAYS_CREATE);
	asIScriptModule *mod2 = engine->GetModule("m2", asGM_ALWAYS_CREATE);	

	const char* script_text = "void main() { MyTmpl<int> s; }";

	mod1->AddScriptSection("test1", script_text);
	mod1->Build();

	mod2->AddScriptSection("test2", script_text);
	mod2->Build();

	mod1->Discard();

	asIScriptContext *ctx = engine->CreateContext();
	asIScriptFunction *func = mod2->GetFunctionByDecl("void main()");
	ctx->Prepare(func);
	ctx->Execute();
	ctx->Release();

	engine->Release();

 

Share this post


Link to post
Share on other sites
Advertisement

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!