Advertisement

assertion failure in as_compiler.cpp

Started by February 21, 2009 05:03 PM
7 comments, last by _Vicious_ 15 years, 9 months ago
hello, again! sometimes in debug builds I get an assertion failure in as_compiler.cpp like 448: asASSERT(variableAllocations.GetLength() == freeVariables.GetLength()); This is a WIP version of AS and I only get this assertion failure when a particular script is run. What information should I additionally provide for this issue to be resolved? The script itself is rather hairy and consists of several files so I think it's going to be rather difficult to dissect it into a simple testcase.
For assert failures like these I really need to be able to reproduce the problem. I need a piece of code that reliably reproduces the problem so that I can debug it. If you can't create a simple testcase, perhaps you can create any testcase, even a complex one.

However, I shouldn't think it would be too difficult to create a simple test case. Especially since this is an error in the compiler, rather than the VM. Take your script, and comment out as much as possible while still reproducing.

It may be useful to check in which function the assert occurs. If you debug the application when the assert fails, you'll find the outFunc member in the CCompiler class. This member holds the name of the function that is currently being compiled.


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

Advertisement
Ok, here's the offending code:

cEntity @GENERIC_CommandDropItem( cClient @client, cString @argsString ){    cItem @item;    cEntity @dropped;    @item = @G_GetItemByName( argsString );    if ( @item == null )        return null;    int count = client.inventoryCount( item.tag );    if ( ( item.type & IT_HEALTH ) != 0 )    {		@dropped = @client.getEnt().dropItem( item.tag );		if ( @dropped == null )			client.printMessage( "Couldn't drop a "  + item.getName() + "\n" );		else			client.getEnt().health -= float( item.quantity );    }    else    {        @dropped = @client.getEnt().dropItem( item.tag );        if ( @dropped == null )            client.printMessage( "Couldn't drop a "  + item.getName() + "\n" );        else        {            count--;            client.inventorySetCount( item.tag, count );        }    }    return dropped;}


Commenting out the
		else			client.getEnt().health -= float( item.quantity );
block fixes the assertion
Thanks for narrowing it down. I'll look into 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 been able to reproduce the error with the following script:

	void GENERIC_CommandDropItem( cClient @client )	{		client.getEnt().health -= 1;	}


You can work around the bug, by breaking the statement in two:

	void GENERIC_CommandDropItem( cClient @client )	{		cEntity @ent = client.getEnt();		ent.health -= 1;	}


Hopefully I'll have a bug fix ready soon.

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

great, thanks!
Advertisement
To fix this bug, the method asCCompiler::DoAssignment must be modified as follows:

int asCCompiler::DoAssignment(asSExprContext *ctx, asSExprContext *lctx, asSExprContext *rctx, asCScriptNode *lexpr, asCScriptNode *rexpr, int op, asCScriptNode *opNode){	// Implicit handle types should always be treated as handles in assignments	if (lctx->type.dataType.GetObjectType() && (lctx->type.dataType.GetObjectType()->flags & asOBJ_IMPLICIT_HANDLE) )	{		lctx->type.dataType.MakeHandle(true);		lctx->type.isExplicitHandle = true;	}	if( lctx->type.dataType.IsPrimitive() )	{		if( op != ttAssignment )		{			// Compute the operator before the assignment			asCTypeInfo lvalue = lctx->type;// Line 4624: Add the following if statement			if( lctx->type.isTemporary && !lctx->type.isVariable )			{				// The temporary variable must not be freed until 				// the assignment has been performed. lvalue holds				// the information about the temporary variable				lctx->type.isTemporary = false;			}// end of fix			asSExprContext o(engine);			CompileOperator(opNode, lctx, rctx, &o);			MergeExprContexts(rctx, &o);			rctx->type = o.type;   ... 


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

The fix is now checked in to the SVN.

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

Verified as fixed :)

This topic is closed to new replies.

Advertisement