Advertisement

Issue in registering template specialization?

Started by October 30, 2014 02:43 PM
16 comments, last by WitchLord 10 years ago

I was trying to use the aatc library today, when I call aatc_RegisterAllContainers(), the script engine gives an error of "ConfigError(asNOT_SUPPORTED, "RegisterObjectType", name, 0)" in asCScriptEngine::RegisterObjectType at line 1915, while the aatc is registering the template specialization vector<int8>, it looks as if the condition of the if-statement is always satisfied.

At line 1849 ,there is:


// Keep the most recent template generated instance type, so we know what it was before parsing the datatype
asCObjectType *mostRecentTemplateInstanceType = 0;
if( generatedTemplateTypes.GetLength() )
	mostRecentTemplateInstanceType = generatedTemplateTypes[generatedTemplateTypes.GetLength()-1];

And at line 1911 there is


if( (generatedTemplateTypes.GetLength() &&
	 generatedTemplateTypes[generatedTemplateTypes.GetLength()-1] == mostRecentTemplateInstanceType) ||
	mostRecentTemplateInstanceType == dt.GetObjectType() )
	// TODO: Should have a better error message
	return ConfigError(asNOT_SUPPORTED, "RegisterObjectType", name, 0);

Is it an issue ,or am i misunderstanding the code?

It sounds like your code is trying to register the template specialization vector<int8> twice for some reason.

I was able to get the same error (asNOT_SUPPORTED) with this code:


aatc_RegisterAllContainers(engine);
aatc_register_container_tempspec_vector<aatc_type_int8, 1, 1, 0>(engine, "int8");

aatc_RegisterAllContainers() already registers template specializations for all primitives for the container types:

  • vector
  • list
  • set
  • unordered_set

so you shouldn't be registering template specializations of primitives for those containers manually.

Is AATC the only thing registering template types in your project?

If not, maybe its a name conflict with some other library who also likes registering template specializations with the name "vector".

If you think its a name conflict, you can try changing the name of the aatc vector container in aatc_config.hpp


#define aatc_name_script_container_vector "vector"

and see if that works.

Advertisement
'll look into this. It might be a bug in angelscript, or else aatc is trying to register the template specialization in some incorrect way.

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

The error condition on line 1915 (asNOT_SUPPORTED) only happens if the template specialization that you're attempting to register already exists as a generated template instance. For example if some other code had already used 'vector<int8>' during a registration, or while compiling a script.

Observe, this condition is not the same as when the template specialization is already registered. That condition will return the error asALREADY_REGISTERED;

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

After further testing I detected that there was indeed a problem with the condition. It could incorrectly give the error asNOT_SUPPORTED instead of asALREADY_REGISTERED in a specific scenario.

I've fixed this in revision 2033. Thanks.

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

There is still someting wrong,I wrote the code bellow at the begin of asCScriptEngine::RegisterObjectType:


printf("------------------------------------------------------------------\n");
	printf("Begin Register Type %s:\n", name);
	for (int i = 0; i < generatedTemplateTypes.GetLength(); ++i)
	{
		auto v = generatedTemplateTypes[i];
		if (v->templateSubTypes.GetLength() > 0)
		{
			if (v->templateSubTypes[0].GetObjectType())
			{
				printf("%s<%s>\n", v->name.AddressOf(), v->templateSubTypes[0].GetObjectType()->name.AddressOf());
			}
			else
			{
				printf("%s<%s>\n", v->name.AddressOf(), asCTokenizer::GetDefinition(v->templateSubTypes[0].GetTokenType()));
			}
		}
		else
		{
			printf("%s\n", v->name.AddressOf());
		}
	}

and the code bellow at the end of asCScriptEngine::RegisterObjectType:


printf("End Register Type %s:\n", name);
	for (int i = 0; i < generatedTemplateTypes.GetLength(); ++i)
	{
		auto v = generatedTemplateTypes[i];
		if (v->templateSubTypes.GetLength() > 0)
		{
			if (v->templateSubTypes[0].GetObjectType())
			{
				printf("%s<%s>\n", v->name.AddressOf(), v->templateSubTypes[0].GetObjectType()->name.AddressOf());
			}
			else
			{
				printf("%s<%s>\n", v->name.AddressOf(), asCTokenizer::GetDefinition(v->templateSubTypes[0].GetTokenType()));
			}
		}
		else
		{
			printf("%s\n", v->name.AddressOf());
		}
	}
	printf("------------------------------------------------------------------\n");

and it outputs:


------------------------------------------------------------------
Begin Register Type vector<int8>:
End Register Type vector<int8>:
vector_iterator<int8>
------------------------------------------------------------------

why it registered vector<int8> but got vector_iterator<int8>?

Advertisement

I developed AATC using Angelscript version 2.29.1 and everything worked fine. Today I got AS svn revision 2033 now I'm getting the same error.

The only AATC function that my game project calls is aatc_RegisterAllContainers(engine);

With AS 2.29.1 it worked perfectly, with the latest svn version I get these errors:


SCRIPT ERROR ::  , row 0 , type=0 , msg=Cannot register template specialization. The template type instance 'vector_iterator<int8>' has already been generated.
SCRIPT ERROR ::  , row 0 , type=0 , msg=Failed in call to function 'RegisterObjectType' with 'vector_iterator<int8>' (Code: -7)
Assertion failed: r >= 0, file c:\****\aatc_shared_tempspec.hpp, line 495

Its complaining about the iterators, but not the containers.

AATC is registering its types in this order:


register type template "container<T>"
register type template "container_iterator<T>"

register type tempspec "container<int8>"
register type tempspec "container_iterator<int8>"
register type tempspec "container<int16>"
register type tempspec "container_iterator<int16>"
...
register type tempspec "container<float64>"
register type tempspec "container_iterator<float64>"

Its strange how it complains about iterators being already registered, but not the containers.

The containers are ref types and iterators are value types.

Registering a container tempspec ends up looking like this:


r = engine->RegisterObjectType("vector<int8>", 0, asOBJ_REF); assert(r >= 0);
Registering an iterator tempspec ends up looking like this:

r = engine->RegisterObjectType("vector_iterator<int8>", sizeof(aect_iterator_shared_tempspec), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<aect_iterator_shared_tempspec>()); assert(r >= 0);

I think I understand where the problem is. I'll need to do some more investigation to confirm this and fix this, but here's what I believe is happening:

When the vector<int8> specialization is registered, the engine generates the vector_iterator<int8> automatically due to vector<T> having a method that takes or returns an iterator. Because of this when the vector_iterator<int8> is being registered it fails, because it already exists.

This is exactly what the test that glcolor did shows. After registering vector<int8> the generatedTemplateTypes contains the vector_iterator<int8>.

It's a bit difficult to read the aatc source code due to all the template magic that is going on, but if I'm not mistaken the culprit is this one:

https://github.com/Sami-Vuorela/aatc/blob/master/source/aatc_vector_template.cpp (lines 98 and 99)

 sprintf_s(textbuf, 1000, "%s begin()", n_iterator_TT);
 r = engine->RegisterObjectMethod(n_container_T, textbuf, asFunctionPtr(aatc_reghelp_construct_hosted_iterator_template<aect_iterator_shared_template<aatc_container_vector_template>, aatc_container_vector_template*>), asCALL_CDECL_OBJLAST); assert(r >= 0);

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 is likely a problem in AngelScript. As far as I can tell aatc is registering the template specialization correctly, i.e.

RegisterObjectType("vector<int8>", ...);
RegisterObjectType("vector_iterator<int8>", ...);
RegisterObjectMethod("vector<int8>", "vector_iterator<int8> begin()", ...);

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

Just tested different AS versions again.

Same AATC code, only aatc_RegisterAllContainers called.

Angelscript 2.29.1 works

Angelscript 2.29.2 throws asNOT_SUPPORTED, without the useful error string ("already generated something something")

Angelscript svn 2033 throws asNOT_SUPPORTED, with the useful error string ("already generated something something")

Something terrifying must have happened to template specializations between AS 2.29.1 and 2.29.2

This topic is closed to new replies.

Advertisement