🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Template Factory Return Type Bug

Started by
2 comments, last by WitchLord 5 years, 6 months ago

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();

 

Advertisement

Thanks. I'll investigate 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

I've fixed this in revision 2563

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

This topic is closed to new replies.

Advertisement