debugging context

Started by
15 comments, last by kunitoki 17 years, 10 months ago
i'm building a complete extensible ide for angelscript. actually when debugging code, i would like to show at least the current stack variables defined, and i'm doing: int varNumber = context->GetVarCount (); if (varNumber > 0) { for (int i = 0; i < varNumber; i++) { void* varPointer = context->GetVarPointer (i); currentVarStack << context->GetVarDeclaration (i) << " : 0x" << String().toHexString((int)varPointer) << "\n"; } } else currentVarStack << "No variables on stack" << "\n"; supportPanel->replaceVariablesText (currentVarStack ); in this code i could determine the declaration of the variables, but i would like to cast the void* to its real value, based on the type id. i means, i don't want to know the value of an object, but i would like to cast the void* to base types value (only bool,int,float...). how can i do that ?
Advertisement
The declaration gives you the type of the variable; ultimatly you will have to perform some sort of switch on the type name or use a polymorphic holder class.
i've done already for the basic types, a couple of casts have done the job.
now i need to implement a sort of object property traversing methods...
You have the benefit here of having access to the code that bound those types too. From your other thread, I got the impression you are using DLLs to bind types to angelscript. You could require these DLLs to supply the reflection information as well.
yes i'm defining a new interface for libraries to handle all this stuff...
actually i'm having troubles getting the void* of a callstack variable to be casted to its correct type. i mean, casting basic types is working like this:

String typeDecl = String(*(float*)(varPointer));

but then when i encounter a type id which refer to a "String" object i've tryed everything, but every cast that i make is referring to an object that seems not the type that i expect:

String typeDecl = ((asString *)varPointer)->buffer;

and "String" is the main c++ type for strings that i have here.
the "asString" is the wrapper class that is like this (shortly):

class asString
{
// ...
String buffer;
protected
int refCount;
//...
}

i'm starting thinking that the void* that i get from conext current callstack
is of type asIScriptGeneric or asIScriptStruct. i'm wrong ? i can't cast directly the type that i'm getting from the context ?



For all non-primitives, you're actually receiving a pointer to a pointer, because that's how the objects are stored on the script stack.

You'll need to do the following:

String typeDecl = (*(asString**)varPointer)->buffer;


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

gr8 ;)
i thought was something like this. thanx andreas.
i'm doing like this, but no success.

// debug mode script line callback...int varNumber = context->GetVarCount ();if (varNumber > 0){	for (int i = 0; i < varNumber; i++)	{		void* varPointer = context->getVarPointer (i);		int typeID = engine->getTypeIdByDecl (0, context->GetVarDeclaration (i));		String varSerialized = engine->serializeVariableFromTypeId (typeID, varPointer);		currentCallStack << 		"[0x" << String().toHexString((int)varPointer) << "] : " <<		context->GetVarDeclaration (i) << " = " << varSerialized << "\n";	}}// the serializeVariableFromTypeId implementationString ScriptableEngine::serializeVariableFromTypeId (const int typeID, void* varPointer){	String typeDecl = getTypeDeclaration (typeID);	if (typeDecl == T("bool"))	{		typeDecl = String((int)*(bool*)(varPointer));	}	else if (typeDecl == T("int8") ||		typeDecl == T("int16") ||		typeDecl == T("int32") ||		typeDecl == T("int"))	{		typeDecl = String(*(int*)(varPointer));	}	else if (typeDecl == T("uint8") ||		typeDecl == T("uint16") ||		typeDecl == T("uint32") ||		typeDecl == T("uint"))	{		typeDecl = String((int)*(unsigned int*)(varPointer));	}	else if (typeDecl == T("float"))	{		typeDecl = String(*(float*)(varPointer));	}	else if (typeDecl == T("double"))	{		typeDecl = String(*(double*)(varPointer));	}	else if (typeDecl == T("String"))	{		asString* str = *((asString**) varPointer);		typeDecl = str->buffer;	}	else	{		typeDecl = extensionManager->serializeVariableFromTypeDecl (typeDecl,varPointer);		if (typeDecl == String::empty)			typeDecl = T("???");	}	return typeDecl;}


i'm still getting leaks when i try to access str->buffer, from debugging i see that it cannot resolve the proper cast to the object. ah the string wrapper is registered extending the asCScriptString example, with the same constructor, addref/release alloc and string factory functions. what i'm doing wrong ?
I just made a test for this to make sure that it really works as I'm saying it should work.

This is the function that I wrote to print the variables in the call stack:

void PrintVariables(asIScriptContext *ctx, int stackLevel){  int numVars = ctx->GetVarCount(stackLevel);  asIScriptEngine *engine = ctx->GetEngine();  for( int n = 0; n < numVars; n++ )  {    int typeId = engine->GetTypeIdByDecl(0, ctx->GetVarDeclaration(n, 0, stackLevel));     if( typeId == engine->GetTypeIdByDecl(0, "int") )    {      print(" %s = %d\n", ctx->GetVarDeclaration(n, 0, stackLevel),        *(int*)ctx->GetVarPointer(n, stackLevel));    }    else if( typeId == engine->GetTypeIdByDecl(0, "string") )    {      print(" %s = '%s'\n", ctx->GetVarDeclaration(n, 0, stackLevel),        (*(asCScriptString**)ctx->GetVarPointer(n, stackLevel))->buffer.c_str());    }  }}


It works just fine, with the following output:

--- call stack ---Module1:void main():8,2 int a = 1 string s = 'text'Module2:void Test2():5,2 int b = 2


I can't see what might be wrong with your code. It seems to be correct.

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